From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 16abc158e55..7697b8f0354 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1337,8 +1337,9 @@ static void heap_set_debug_flags( HANDLE handle ) if (block_get_flags( block ) & BLOCK_FLAG_FREE) { char *data = (char *)block + block_get_overhead( block ), *end = (char *)block + block_get_size( block ); - if (end >= commit_end) mark_block_free( data, commit_end - data, flags ); - else mark_block_free( data, end - sizeof(struct block *) - data, flags ); + if (next_block( subheap, block )) end -= sizeof(struct block *); + if (end > commit_end) mark_block_free( data, commit_end - data, flags ); + else mark_block_free( data, end - data, flags ); } else {
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 62 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 7697b8f0354..f9cdb6d8c26 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -307,54 +307,56 @@ static inline BOOL check_subheap( const SUBHEAP *subheap )
static BOOL heap_validate( const HEAP *heap );
-/* mark a block of memory as free for debugging purposes */ -static inline void mark_block_free( void *ptr, SIZE_T size, DWORD flags ) +/* mark a block of memory as innacessible for debugging purposes */ +static inline void valgrind_make_noaccess( void const *ptr, SIZE_T size ) { - if (flags & HEAP_FREE_CHECKING_ENABLED) - { - SIZE_T i; - for (i = 0; i < size / sizeof(DWORD); i++) ((DWORD *)ptr)[i] = ARENA_FREE_FILLER; - } #if defined(VALGRIND_MAKE_MEM_NOACCESS) - VALGRIND_DISCARD( VALGRIND_MAKE_MEM_NOACCESS( ptr, size )); -#elif defined( VALGRIND_MAKE_NOACCESS) - VALGRIND_DISCARD( VALGRIND_MAKE_NOACCESS( ptr, size )); + VALGRIND_DISCARD( VALGRIND_MAKE_MEM_NOACCESS( ptr, size ) ); +#elif defined(VALGRIND_MAKE_NOACCESS) + VALGRIND_DISCARD( VALGRIND_MAKE_NOACCESS( ptr, size ) ); #endif }
/* mark a block of memory as initialized for debugging purposes */ -static inline void mark_block_initialized( void *ptr, SIZE_T size ) +static inline void valgrind_make_readable( void const *ptr, SIZE_T size ) { #if defined(VALGRIND_MAKE_MEM_DEFINED) - VALGRIND_DISCARD( VALGRIND_MAKE_MEM_DEFINED( ptr, size )); + VALGRIND_DISCARD( VALGRIND_MAKE_MEM_DEFINED( ptr, size ) ); #elif defined(VALGRIND_MAKE_READABLE) - VALGRIND_DISCARD( VALGRIND_MAKE_READABLE( ptr, size )); + VALGRIND_DISCARD( VALGRIND_MAKE_READABLE( ptr, size ) ); #endif }
/* mark a block of memory as uninitialized for debugging purposes */ -static inline void mark_block_uninitialized( void *ptr, SIZE_T size ) +static inline void valgrind_make_writable( void const *ptr, SIZE_T size ) { #if defined(VALGRIND_MAKE_MEM_UNDEFINED) - VALGRIND_DISCARD( VALGRIND_MAKE_MEM_UNDEFINED( ptr, size )); + VALGRIND_DISCARD( VALGRIND_MAKE_MEM_UNDEFINED( ptr, size ) ); #elif defined(VALGRIND_MAKE_WRITABLE) - VALGRIND_DISCARD( VALGRIND_MAKE_WRITABLE( ptr, size )); + VALGRIND_DISCARD( VALGRIND_MAKE_WRITABLE( ptr, size ) ); #endif }
+/* mark a block of memory as free for debugging purposes */ +static inline void mark_block_free( void *ptr, SIZE_T size, DWORD flags ) +{ + if (flags & HEAP_FREE_CHECKING_ENABLED) + { + SIZE_T i; + for (i = 0; i < size / sizeof(DWORD); i++) ((DWORD *)ptr)[i] = ARENA_FREE_FILLER; + } + valgrind_make_noaccess( ptr, size ); +} + /* mark a block of memory as a tail block */ static inline void mark_block_tail( void *ptr, SIZE_T size, DWORD flags ) { if (flags & HEAP_TAIL_CHECKING_ENABLED) { - mark_block_uninitialized( ptr, size ); + valgrind_make_writable( ptr, size ); memset( ptr, ARENA_TAIL_FILLER, size ); } -#if defined(VALGRIND_MAKE_MEM_NOACCESS) - VALGRIND_DISCARD( VALGRIND_MAKE_MEM_NOACCESS( ptr, size )); -#elif defined( VALGRIND_MAKE_NOACCESS) - VALGRIND_DISCARD( VALGRIND_MAKE_NOACCESS( ptr, size )); -#endif + valgrind_make_noaccess( ptr, size ); }
/* initialize contents of a newly created block of memory */ @@ -362,17 +364,13 @@ static inline void initialize_block( void *ptr, SIZE_T size, SIZE_T unused, DWOR { if (flags & HEAP_ZERO_MEMORY) { - mark_block_initialized( ptr, size ); + valgrind_make_writable( ptr, size ); memset( ptr, 0, size ); } - else + else if (flags & HEAP_FREE_CHECKING_ENABLED) { - mark_block_uninitialized( ptr, size ); - if (flags & HEAP_FREE_CHECKING_ENABLED) - { - memset( ptr, ARENA_INUSE_FILLER, size ); - mark_block_uninitialized( ptr, size ); - } + valgrind_make_writable( ptr, size ); + memset( ptr, ARENA_INUSE_FILLER, size ); }
mark_block_tail( (char *)ptr + size, unused, flags ); @@ -679,7 +677,7 @@ static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T blo DWORD flags = heap->flags; struct block *next;
- mark_block_uninitialized( block, sizeof(*entry) ); + valgrind_make_writable( block, sizeof(*entry) ); block_set_type( block, ARENA_FREE_MAGIC ); block_set_size( block, BLOCK_FLAG_FREE, block_size );
@@ -702,7 +700,7 @@ static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T blo { /* set the next block PREV_FREE flag and back pointer */ block_set_size( next, BLOCK_FLAG_PREV_FREE, block_get_size( next ) ); - mark_block_initialized( (struct block **)next - 1, sizeof(struct block *) ); + valgrind_make_writable( (struct block **)next - 1, sizeof(struct block *) ); *((struct block **)next - 1) = block; }
From: Rémi Bernon rbernon@codeweavers.com
It's allocated from the heap itself, should be freed even for the main process heap, and before destroying the CS or notifying valgrind of used block being freed.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index f9cdb6d8c26..57ceff9cdd1 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1431,6 +1431,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) HEAP *heapPtr = HEAP_GetPtr( heap ); SUBHEAP *subheap, *next; ARENA_LARGE *arena, *arena_next; + struct block **pending, **tmp; SIZE_T size; void *addr;
@@ -1443,6 +1444,15 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) } if (!heapPtr) return heap;
+ if ((pending = heapPtr->pending_free)) + { + heapPtr->pending_free = NULL; + for (tmp = pending; *tmp && tmp != pending + MAX_FREE_PENDING; ++tmp) + if ((subheap = find_subheap( heap, *tmp, FALSE ))) + free_used_block( subheap, *tmp ); + RtlFreeHeap( heap, 0, pending ); + } + if (heap == processHeap) return heap; /* cannot delete the main process heap */
/* remove it from the per-process list */ @@ -1470,7 +1480,6 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); } notify_free_all( &heapPtr->subheap ); - RtlFreeHeap( GetProcessHeap(), 0, heapPtr->pending_free ); size = 0; addr = heap; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 57ceff9cdd1..4050c00c265 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -377,7 +377,7 @@ static inline void initialize_block( void *ptr, SIZE_T size, SIZE_T unused, DWOR }
/* notify that a new block of memory has been allocated for debugging purposes */ -static inline void notify_alloc( void *ptr, SIZE_T size, BOOL init ) +static inline void valgrind_notify_alloc( void const *ptr, SIZE_T size, BOOL init ) { #ifdef VALGRIND_MALLOCLIKE_BLOCK VALGRIND_MALLOCLIKE_BLOCK( ptr, size, 0, init ); @@ -385,14 +385,14 @@ 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 const *ptr ) +static inline void valgrind_notify_free( void const *ptr ) { #ifdef VALGRIND_FREELIKE_BLOCK VALGRIND_FREELIKE_BLOCK( ptr, 0 ); #endif }
-static inline void notify_realloc( void const *ptr, SIZE_T size_old, SIZE_T size_new ) +static inline void valgrind_notify_resize( void const *ptr, SIZE_T size_old, SIZE_T size_new ) { #ifdef VALGRIND_RESIZEINPLACE_BLOCK /* zero is not a valid size */ @@ -400,7 +400,7 @@ static inline void notify_realloc( void const *ptr, SIZE_T size_old, SIZE_T size #endif }
-static void notify_free_all( SUBHEAP *subheap ) +static void valgrind_notify_free_all( SUBHEAP *subheap ) { #ifdef VALGRIND_FREELIKE_BLOCK struct block *block; @@ -411,7 +411,7 @@ static void notify_free_all( SUBHEAP *subheap ) for (block = first_block( subheap ); block; block = next_block( subheap, block )) { if (block_get_flags( block ) & BLOCK_FLAG_FREE) continue; - if (block_get_type( block ) == ARENA_INUSE_MAGIC) notify_free( block + 1 ); + if (block_get_type( block ) == ARENA_INUSE_MAGIC) valgrind_notify_free( block + 1 ); } #endif } @@ -801,7 +801,6 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size ) arena->magic = ARENA_LARGE_MAGIC; mark_block_tail( (char *)(arena + 1) + size, block_size - sizeof(*arena) - size, flags ); list_add_tail( &heap->large_list, &arena->entry ); - notify_alloc( arena + 1, size, flags & HEAP_ZERO_MEMORY ); return arena + 1; }
@@ -833,11 +832,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz SIZE_T unused = arena->block_size - sizeof(*arena) - size;
/* FIXME: we could remap zero-pages instead */ -#ifdef VALGRIND_RESIZEINPLACE_BLOCK - if (RUNNING_ON_VALGRIND) - notify_realloc( arena + 1, arena->data_size, size ); - else -#endif + valgrind_notify_resize( arena + 1, arena->data_size, size ); if (size > arena->data_size) initialize_block( (char *)ptr + arena->data_size, size - arena->data_size, unused, flags ); else @@ -851,9 +846,10 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz WARN("Could not allocate block for %08lx bytes\n", size ); return NULL; } + valgrind_notify_alloc( new_ptr, size, 0 ); memcpy( new_ptr, ptr, arena->data_size ); + valgrind_notify_free( ptr ); free_large_block( heap, ptr ); - notify_free( ptr ); return new_ptr; }
@@ -1473,13 +1469,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 */ - notify_free_all( subheap ); + valgrind_notify_free_all( subheap ); list_remove( &subheap->entry ); size = 0; addr = ROUND_ADDR( subheap, COMMIT_MASK ); NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); } - notify_free_all( &heapPtr->subheap ); + valgrind_notify_free_all( &heapPtr->subheap ); size = 0; addr = heap; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); @@ -1510,8 +1506,6 @@ static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret
block_set_type( block, ARENA_INUSE_MAGIC ); shrink_used_block( subheap, block, 0, old_block_size, block_size, size ); - - notify_alloc( block + 1, size, flags & HEAP_ZERO_MEMORY ); initialize_block( block + 1, size, block->unused_bytes, flags );
*ret = block + 1; @@ -1536,6 +1530,8 @@ void *WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T heap_unlock( heapPtr, flags ); }
+ if (!status) valgrind_notify_alloc( ptr, size, flags & HEAP_ZERO_MEMORY ); + TRACE( "heap %p, flags %#x, size %#Ix, return %p, status %#x.\n", heap, flags, size, ptr, status ); heap_set_status( heapPtr, flags, status ); return ptr; @@ -1547,9 +1543,6 @@ static NTSTATUS heap_free( HEAP *heap, void *ptr ) ARENA_INUSE *block; SUBHEAP *subheap;
- /* Inform valgrind we are trying to free memory, so it can throw up an error message */ - notify_free( ptr ); - if (!(block = unsafe_block_from_ptr( heap, ptr, &subheap ))) return STATUS_INVALID_PARAMETER; if (!subheap) free_large_block( heap, ptr ); else free_used_block( subheap, block ); @@ -1567,6 +1560,8 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
if (!ptr) return TRUE;
+ valgrind_notify_free( ptr ); + if (!(heapPtr = HEAP_GetPtr( heap ))) status = STATUS_INVALID_PARAMETER; else @@ -1614,23 +1609,24 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size list_remove( &entry->entry ); old_block_size += block_get_size( next ); if (!subheap_commit( subheap, block, block_size )) return STATUS_NO_MEMORY; - notify_realloc( block + 1, old_size, size ); + valgrind_notify_resize( block + 1, old_size, size ); shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); } else { if (flags & HEAP_REALLOC_IN_PLACE_ONLY) return STATUS_NO_MEMORY; if ((status = heap_allocate( heap, flags & ~HEAP_ZERO_MEMORY, size, ret ))) return status; + valgrind_notify_alloc( *ret, size, 0 ); memcpy( *ret, block + 1, old_size ); if (flags & HEAP_ZERO_MEMORY) memset( (char *)*ret + old_size, 0, size - old_size ); - notify_free( ptr ); + valgrind_notify_free( ptr ); free_used_block( subheap, block ); return STATUS_SUCCESS; } } else { - notify_realloc( block + 1, old_size, size ); + valgrind_notify_resize( block + 1, old_size, size ); shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115844
Your paranoid android.
=== debian11 (32 bit Chinese:China report) ===
ntdll: virtual: Timeout
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 4050c00c265..0102ba3ea42 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1609,8 +1609,6 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size list_remove( &entry->entry ); old_block_size += block_get_size( next ); if (!subheap_commit( subheap, block, block_size )) return STATUS_NO_MEMORY; - valgrind_notify_resize( block + 1, old_size, size ); - shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); } else { @@ -1624,13 +1622,9 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size return STATUS_SUCCESS; } } - else - { - valgrind_notify_resize( block + 1, old_size, size ); - shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); - }
- /* Clear the extra bytes if needed */ + valgrind_notify_resize( block + 1, old_size, size ); + shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size );
if (size <= old_size) mark_block_tail( (char *)(block + 1) + size, block->unused_bytes, flags ); else initialize_block( (char *)(block + 1) + old_size, size - old_size, block->unused_bytes, flags );
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/kernel32/tests/heap.c | 7 +++---- dlls/ntdll/heap.c | 30 +++++++++--------------------- 2 files changed, 12 insertions(+), 25 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 8ef0bfc3668..1e99ddf8b39 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -2242,7 +2242,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags ok( diff > expect_size, "got diff %#Ix\n", diff );
tail = ptr0[alloc_size] | ptr1[alloc_size] | ptr2[alloc_size]; - todo_wine_if( heap_flags & HEAP_TAIL_CHECKING_ENABLED ) ok( !tail, "got tail\n" );
ret = HeapFree( heap, 0, ptr2 ); @@ -2492,9 +2491,9 @@ static void test_heap_checks( DWORD flags ) if (flags & HEAP_TAIL_CHECKING_ENABLED) { /* Windows doesn't do tail checking on large blocks */ - ok( p[large_size] == 0xab || broken(p[large_size] == 0), "wrong data %x\n", p[large_size] ); - ok( p[large_size+1] == 0xab || broken(p[large_size+1] == 0), "wrong data %x\n", p[large_size+1] ); - ok( p[large_size+2] == 0xab || broken(p[large_size+2] == 0), "wrong data %x\n", p[large_size+2] ); + ok( p[large_size] == 0, "wrong data %x\n", p[large_size] ); + ok( p[large_size + 1] == 0, "wrong data %x\n", p[large_size + 1] ); + ok( p[large_size + 2] == 0, "wrong data %x\n", p[large_size + 2] ); if (p[large_size] == 0xab) { p[large_size] = 0xcc; diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 0102ba3ea42..00b4cd7e894 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -783,7 +783,7 @@ static inline void shrink_used_block( SUBHEAP *subheap, struct block *block, UIN static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size ) { ARENA_LARGE *arena; - SIZE_T block_size = sizeof(*arena) + ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); + SIZE_T block_size = sizeof(*arena) + ROUND_SIZE( size ); LPVOID address = NULL;
if (!(flags & HEAP_GROWABLE)) return NULL; @@ -799,8 +799,9 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size ) arena->block_size = block_size; arena->size = ARENA_LARGE_SIZE; arena->magic = ARENA_LARGE_MAGIC; - mark_block_tail( (char *)(arena + 1) + size, block_size - sizeof(*arena) - size, flags ); list_add_tail( &heap->large_list, &arena->entry ); + valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size, + arena->block_size - sizeof(*arena) - arena->data_size ); return arena + 1; }
@@ -825,19 +826,17 @@ static void free_large_block( HEAP *heap, void *ptr ) static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T size ) { ARENA_LARGE *arena = (ARENA_LARGE *)ptr - 1; + SIZE_T old_size = arena->data_size; void *new_ptr;
if (arena->block_size - sizeof(*arena) >= size) { - SIZE_T unused = arena->block_size - sizeof(*arena) - size; - /* FIXME: we could remap zero-pages instead */ - valgrind_notify_resize( arena + 1, arena->data_size, size ); - if (size > arena->data_size) - initialize_block( (char *)ptr + arena->data_size, size - arena->data_size, unused, flags ); - else - mark_block_tail( (char *)ptr + size, unused, flags ); + valgrind_notify_resize( arena + 1, old_size, size ); + if (size > old_size) initialize_block( (char *)ptr + old_size, size - old_size, 0, flags ); arena->data_size = size; + valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size, + arena->block_size - sizeof(*arena) - arena->data_size ); return ptr; } if (flags & HEAP_REALLOC_IN_PLACE_ONLY) return NULL; @@ -847,7 +846,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz return NULL; } valgrind_notify_alloc( new_ptr, size, 0 ); - memcpy( new_ptr, ptr, arena->data_size ); + memcpy( new_ptr, ptr, old_size ); valgrind_notify_free( ptr ); free_large_block( heap, ptr ); return new_ptr; @@ -877,12 +876,6 @@ static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena ) err = "invalid block header"; else if (!contains( arena, arena->block_size, arena + 1, arena->data_size )) err = "invalid block size"; - else if (heap->flags & HEAP_TAIL_CHECKING_ENABLED) - { - SIZE_T i, unused = arena->block_size - sizeof(*arena) - arena->data_size; - const unsigned char *data = (const unsigned char *)(arena + 1) + arena->data_size; - for (i = 0; i < unused && !err; i++) if (data[i] != ARENA_TAIL_FILLER) err = "invalid block tail"; - }
if (err) { @@ -1317,7 +1310,6 @@ static void heap_set_debug_flags( HANDLE handle ) if (flags & (HEAP_FREE_CHECKING_ENABLED | HEAP_TAIL_CHECKING_ENABLED)) /* fix existing blocks */ { struct block *block; - ARENA_LARGE *large; SUBHEAP *subheap;
LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) @@ -1342,10 +1334,6 @@ static void heap_set_debug_flags( HANDLE handle ) } } } - - LIST_FOR_EACH_ENTRY( large, &heap->large_list, ARENA_LARGE, entry ) - mark_block_tail( (char *)(large + 1) + large->data_size, - large->block_size - sizeof(*large) - large->data_size, flags ); }
if ((heap->flags & HEAP_GROWABLE) && !heap->pending_free &&
Sven Baars (@sbaars) commented about dlls/kernel32/tests/heap.c:
if (flags & HEAP_TAIL_CHECKING_ENABLED) { /* Windows doesn't do tail checking on large blocks */
ok( p[large_size] == 0xab || broken(p[large_size] == 0), "wrong data %x\n", p[large_size] );
ok( p[large_size+1] == 0xab || broken(p[large_size+1] == 0), "wrong data %x\n", p[large_size+1] );
ok( p[large_size+2] == 0xab || broken(p[large_size+2] == 0), "wrong data %x\n", p[large_size+2] );
ok( p[large_size] == 0, "wrong data %x\n", p[large_size] );
ok( p[large_size + 1] == 0, "wrong data %x\n", p[large_size + 1] );
ok( p[large_size + 2] == 0, "wrong data %x\n", p[large_size + 2] ); if (p[large_size] == 0xab)
Isn't this if statement unreachable now according to the test above?
On Tue May 31 09:35:40 2022 +0000, Sven Baars wrote:
Isn't this if statement unreachable now according to the test above?
Ah yeah indeed, thanks.