John Reiser : ntdll: When tracking allocated blocks, RtlDestroyHeap must notify that all the blocks are being freed.

Alexandre Julliard julliard at winehq.org
Fri Jul 25 08:13:10 CDT 2008


Module: wine
Branch: master
Commit: d6f469110674c1d89b3344de62bc421c5051918a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d6f469110674c1d89b3344de62bc421c5051918a

Author: John Reiser <jreiser at BitWagon.com>
Date:   Thu Jul 24 10:21:01 2008 -0700

ntdll: When tracking allocated blocks, RtlDestroyHeap must notify that all the blocks are being freed.

---

 dlls/ntdll/heap.c |   30 +++++++++++++++++++++++++++++-
 1 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index d57db49..44b88b2 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -193,13 +193,39 @@ static inline void notify_alloc( void *ptr, SIZE_T size, BOOL init )
 }
 
 /* notify that a block of memory has been freed for debugging purposes */
-static inline void notify_free( void *ptr )
+static inline void notify_free( void const *ptr )
 {
 #ifdef VALGRIND_FREELIKE_BLOCK
     VALGRIND_FREELIKE_BLOCK( ptr, 0 );
 #endif
 }
 
+static void subheap_notify_free_all(SUBHEAP const *subheap)
+{
+#ifdef VALGRIND_FREELIKE_BLOCK
+    char const *ptr = (char const *)subheap->base + subheap->headerSize;
+
+    if (!RUNNING_ON_VALGRIND) return;
+
+    while (ptr < (char const *)subheap->base + subheap->size)
+    {
+        if (*(const DWORD *)ptr & ARENA_FLAG_FREE)
+        {
+            ARENA_FREE const *pArena = (ARENA_FREE const *)ptr;
+            if (pArena->magic!=ARENA_FREE_MAGIC) ERR("bad free_magic @%p\n", pArena);
+            ptr += sizeof(*pArena) + (pArena->size & ARENA_SIZE_MASK);
+        }
+        else
+        {
+            ARENA_INUSE const *pArena = (ARENA_INUSE const *)ptr;
+            if (pArena->magic!=ARENA_INUSE_MAGIC) ERR("bad inuse_magic @%p\n", pArena);
+            notify_free(pArena + 1);
+            ptr += sizeof(*pArena) + (pArena->size & ARENA_SIZE_MASK);
+        }
+    }
+#endif
+}
+
 /* locate a free list entry of the appropriate size */
 /* size is the size of the whole block including the arena header */
 static inline unsigned int get_freelist_index( SIZE_T size )
@@ -1148,11 +1174,13 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
     LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heapPtr->subheap_list, SUBHEAP, entry )
     {
         if (subheap == &heapPtr->subheap) continue;  /* do this one last */
+        subheap_notify_free_all(subheap);
         list_remove( &subheap->entry );
         size = 0;
         addr = subheap->base;
         NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
     }
+    subheap_notify_free_all(&heapPtr->subheap);
     size = 0;
     addr = heapPtr->subheap.base;
     NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );




More information about the wine-cvs mailing list