Added support for marking heap blocks as inaccessible/uninitialized if

valgrind is installed, based on a patch by Adam Gundy.
This commit is contained in:
Alexandre Julliard 2003-04-02 01:42:06 +00:00
parent 9ee2413700
commit c44555bb37
4 changed files with 64 additions and 19 deletions

2
configure vendored
View File

@ -13459,6 +13459,7 @@ done
for ac_header in \ for ac_header in \
@ -13532,6 +13533,7 @@ for ac_header in \
termios.h \ termios.h \
unistd.h \ unistd.h \
utime.h \ utime.h \
valgrind/memcheck.h
do do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`

View File

@ -1072,6 +1072,7 @@ AC_CHECK_HEADERS(\
termios.h \ termios.h \
unistd.h \ unistd.h \
utime.h \ utime.h \
valgrind/memcheck.h
) )
AC_HEADER_STAT() AC_HEADER_STAT()

View File

@ -25,6 +25,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
@ -143,6 +146,45 @@ static void set_process_heap( HANDLE heap )
processHeap = heap; processHeap = heap;
} }
/* mark a block of memory as free for debugging purposes */
static inline void mark_block_free( void *ptr, size_t size )
{
if (TRACE_ON(heap)) memset( ptr, ARENA_FREE_FILLER, size );
#ifdef 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 )
{
#ifdef VALGRIND_MAKE_READABLE
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 )
{
#ifdef VALGRIND_MAKE_WRITABLE
VALGRIND_DISCARD( VALGRIND_MAKE_WRITABLE( ptr, size ));
#endif
if (TRACE_ON(heap))
{
memset( ptr, ARENA_INUSE_FILLER, size );
#ifdef VALGRIND_MAKE_WRITABLE
/* make it uninitialized to valgrind again */
VALGRIND_DISCARD( VALGRIND_MAKE_WRITABLE( ptr, size ));
#endif
}
}
/* clear contents of a block of memory */
static inline void clear_block( void *ptr, size_t size )
{
mark_block_initialized( ptr, size );
memset( ptr, 0, size );
}
/*********************************************************************** /***********************************************************************
* HEAP_Dump * HEAP_Dump
@ -345,22 +387,18 @@ static inline BOOL HEAP_Decommit( SUBHEAP *subheap, void *ptr )
static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size ) static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size )
{ {
ARENA_FREE *pFree; ARENA_FREE *pFree;
char *pEnd;
/* Create a free arena */ /* Create a free arena */
mark_block_uninitialized( ptr, sizeof( ARENA_FREE ) );
pFree = (ARENA_FREE *)ptr; pFree = (ARENA_FREE *)ptr;
pFree->magic = ARENA_FREE_MAGIC; pFree->magic = ARENA_FREE_MAGIC;
/* If debugging, erase the freed block content */ /* If debugging, erase the freed block content */
if (TRACE_ON(heap)) pEnd = (char *)ptr + size;
{ if (pEnd > (char *)subheap + subheap->commitSize) pEnd = (char *)subheap + subheap->commitSize;
char *pEnd = (char *)ptr + size; if (pEnd > (char *)(pFree + 1)) mark_block_free( pFree + 1, pEnd - (char *)(pFree + 1) );
if (pEnd > (char *)subheap + subheap->commitSize)
pEnd = (char *)subheap + subheap->commitSize;
if (pEnd > (char *)(pFree + 1))
memset( pFree + 1, ARENA_FREE_FILLER, pEnd - (char *)(pFree + 1) );
}
/* Check if next block is free also */ /* Check if next block is free also */
@ -372,8 +410,7 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size )
pNext->next->prev = pNext->prev; pNext->next->prev = pNext->prev;
pNext->prev->next = pNext->next; pNext->prev->next = pNext->next;
size += (pNext->size & ARENA_SIZE_MASK) + sizeof(*pNext); size += (pNext->size & ARENA_SIZE_MASK) + sizeof(*pNext);
if (TRACE_ON(heap)) mark_block_free( pNext, sizeof(ARENA_FREE) );
memset( pNext, ARENA_FREE_FILLER, sizeof(ARENA_FREE) );
} }
/* Set the next block PREV_FREE flag and pointer */ /* Set the next block PREV_FREE flag and pointer */
@ -382,6 +419,7 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size )
{ {
DWORD *pNext = (DWORD *)((char *)ptr + size); DWORD *pNext = (DWORD *)((char *)ptr + size);
*pNext |= ARENA_FLAG_PREV_FREE; *pNext |= ARENA_FLAG_PREV_FREE;
mark_block_initialized( pNext - 1, sizeof( ARENA_FREE * ) );
*(ARENA_FREE **)(pNext - 1) = pFree; *(ARENA_FREE **)(pNext - 1) = pFree;
} }
@ -1089,9 +1127,9 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, ULONG size )
HEAP_ShrinkBlock( subheap, pInUse, size ); HEAP_ShrinkBlock( subheap, pInUse, size );
if (flags & HEAP_ZERO_MEMORY) if (flags & HEAP_ZERO_MEMORY)
memset( pInUse + 1, 0, pInUse->size & ARENA_SIZE_MASK ); clear_block( pInUse + 1, pInUse->size & ARENA_SIZE_MASK );
else if (TRACE_ON(heap)) else
memset( pInUse + 1, ARENA_INUSE_FILLER, pInUse->size & ARENA_SIZE_MASK ); mark_block_uninitialized( pInUse + 1, pInUse->size & ARENA_SIZE_MASK );
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
@ -1254,6 +1292,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, ULONG size
+ sizeof(ARENA_FREE) - sizeof(ARENA_INUSE); + sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
pInUse->magic = ARENA_INUSE_MAGIC; pInUse->magic = ARENA_INUSE_MAGIC;
HEAP_ShrinkBlock( newsubheap, pInUse, size ); HEAP_ShrinkBlock( newsubheap, pInUse, size );
mark_block_initialized( pInUse + 1, oldSize );
memcpy( pInUse + 1, pArena + 1, oldSize ); memcpy( pInUse + 1, pArena + 1, oldSize );
/* Free the previous block */ /* Free the previous block */
@ -1270,11 +1309,11 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, ULONG size
if (size > oldSize) if (size > oldSize)
{ {
if (flags & HEAP_ZERO_MEMORY) if (flags & HEAP_ZERO_MEMORY)
memset( (char *)(pArena + 1) + oldSize, 0, clear_block( (char *)(pArena + 1) + oldSize,
(pArena->size & ARENA_SIZE_MASK) - oldSize ); (pArena->size & ARENA_SIZE_MASK) - oldSize );
else if (TRACE_ON(heap)) else
memset( (char *)(pArena + 1) + oldSize, ARENA_INUSE_FILLER, mark_block_uninitialized( (char *)(pArena + 1) + oldSize,
(pArena->size & ARENA_SIZE_MASK) - oldSize ); (pArena->size & ARENA_SIZE_MASK) - oldSize );
} }
/* Return the new arena */ /* Return the new arena */

View File

@ -626,6 +626,9 @@
/* Define to 1 if you have the <utime.h> header file. */ /* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H #undef HAVE_UTIME_H
/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
#undef HAVE_VALGRIND_MEMCHECK_H
/* Define if we have va_copy */ /* Define if we have va_copy */
#undef HAVE_VA_COPY #undef HAVE_VA_COPY