mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-11 19:19:01 +00:00
ntdll: When tracking allocated blocks, RtlDestroyHeap must notify that all the blocks are being freed.
This commit is contained in:
parent
0a2c94e823
commit
d6f4691106
|
@ -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 */
|
/* 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
|
#ifdef VALGRIND_FREELIKE_BLOCK
|
||||||
VALGRIND_FREELIKE_BLOCK( ptr, 0 );
|
VALGRIND_FREELIKE_BLOCK( ptr, 0 );
|
||||||
#endif
|
#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 */
|
/* locate a free list entry of the appropriate size */
|
||||||
/* size is the size of the whole block including the arena header */
|
/* size is the size of the whole block including the arena header */
|
||||||
static inline unsigned int get_freelist_index( SIZE_T size )
|
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 )
|
LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heapPtr->subheap_list, SUBHEAP, entry )
|
||||||
{
|
{
|
||||||
if (subheap == &heapPtr->subheap) continue; /* do this one last */
|
if (subheap == &heapPtr->subheap) continue; /* do this one last */
|
||||||
|
subheap_notify_free_all(subheap);
|
||||||
list_remove( &subheap->entry );
|
list_remove( &subheap->entry );
|
||||||
size = 0;
|
size = 0;
|
||||||
addr = subheap->base;
|
addr = subheap->base;
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||||
}
|
}
|
||||||
|
subheap_notify_free_all(&heapPtr->subheap);
|
||||||
size = 0;
|
size = 0;
|
||||||
addr = heapPtr->subheap.base;
|
addr = heapPtr->subheap.base;
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||||
|
|
Loading…
Reference in a new issue