Commit a855148a authored by Noah Misch's avatar Noah Misch

Refactor aset.c and mcxt.c in preparation for Valgrind cooperation.

Move some repeated debugging code into functions and store intermediates
in variables where not presently necessary.  No code-generation changes
in a production build, and no functional changes.  This simplifies and
focuses the main patch.
parent 1d96bb96
...@@ -308,6 +308,37 @@ AllocSetFreeIndex(Size size) ...@@ -308,6 +308,37 @@ AllocSetFreeIndex(Size size)
return idx; return idx;
} }
#ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */
static void
wipe_mem(void *ptr, size_t size)
{
memset(ptr, 0x7F, size);
}
#endif
#ifdef MEMORY_CONTEXT_CHECKING
static void
set_sentinel(void *base, Size offset)
{
char *ptr = (char *) base + offset;
*ptr = 0x7E;
}
static bool
sentinel_ok(const void *base, Size offset)
{
const char *ptr = (const char *) base + offset;
bool ret;
ret = *ptr == 0x7E;
return ret;
}
#endif
#ifdef RANDOMIZE_ALLOCATED_MEMORY #ifdef RANDOMIZE_ALLOCATED_MEMORY
/* /*
...@@ -492,8 +523,7 @@ AllocSetReset(MemoryContext context) ...@@ -492,8 +523,7 @@ AllocSetReset(MemoryContext context)
char *datastart = ((char *) block) + ALLOC_BLOCKHDRSZ; char *datastart = ((char *) block) + ALLOC_BLOCKHDRSZ;
#ifdef CLOBBER_FREED_MEMORY #ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */ wipe_mem(datastart, block->freeptr - datastart);
memset(datastart, 0x7F, block->freeptr - datastart);
#endif #endif
block->freeptr = datastart; block->freeptr = datastart;
block->next = NULL; block->next = NULL;
...@@ -502,8 +532,7 @@ AllocSetReset(MemoryContext context) ...@@ -502,8 +532,7 @@ AllocSetReset(MemoryContext context)
{ {
/* Normal case, release the block */ /* Normal case, release the block */
#ifdef CLOBBER_FREED_MEMORY #ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */ wipe_mem(block, block->freeptr - ((char *) block));
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif #endif
free(block); free(block);
} }
...@@ -545,8 +574,7 @@ AllocSetDelete(MemoryContext context) ...@@ -545,8 +574,7 @@ AllocSetDelete(MemoryContext context)
AllocBlock next = block->next; AllocBlock next = block->next;
#ifdef CLOBBER_FREED_MEMORY #ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */ wipe_mem(block, block->freeptr - ((char *) block));
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif #endif
free(block); free(block);
block = next; block = next;
...@@ -598,7 +626,7 @@ AllocSetAlloc(MemoryContext context, Size size) ...@@ -598,7 +626,7 @@ AllocSetAlloc(MemoryContext context, Size size)
chunk->requested_size = size; chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */ /* set mark to catch clobber of "unused" space */
if (size < chunk_size) if (size < chunk_size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E; set_sentinel(AllocChunkGetPointer(chunk), size);
#endif #endif
#ifdef RANDOMIZE_ALLOCATED_MEMORY #ifdef RANDOMIZE_ALLOCATED_MEMORY
/* fill the allocated space with junk */ /* fill the allocated space with junk */
...@@ -644,7 +672,7 @@ AllocSetAlloc(MemoryContext context, Size size) ...@@ -644,7 +672,7 @@ AllocSetAlloc(MemoryContext context, Size size)
chunk->requested_size = size; chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */ /* set mark to catch clobber of "unused" space */
if (size < chunk->size) if (size < chunk->size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E; set_sentinel(AllocChunkGetPointer(chunk), size);
#endif #endif
#ifdef RANDOMIZE_ALLOCATED_MEMORY #ifdef RANDOMIZE_ALLOCATED_MEMORY
/* fill the allocated space with junk */ /* fill the allocated space with junk */
...@@ -801,7 +829,7 @@ AllocSetAlloc(MemoryContext context, Size size) ...@@ -801,7 +829,7 @@ AllocSetAlloc(MemoryContext context, Size size)
chunk->requested_size = size; chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */ /* set mark to catch clobber of "unused" space */
if (size < chunk->size) if (size < chunk->size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E; set_sentinel(AllocChunkGetPointer(chunk), size);
#endif #endif
#ifdef RANDOMIZE_ALLOCATED_MEMORY #ifdef RANDOMIZE_ALLOCATED_MEMORY
/* fill the allocated space with junk */ /* fill the allocated space with junk */
...@@ -827,7 +855,7 @@ AllocSetFree(MemoryContext context, void *pointer) ...@@ -827,7 +855,7 @@ AllocSetFree(MemoryContext context, void *pointer)
#ifdef MEMORY_CONTEXT_CHECKING #ifdef MEMORY_CONTEXT_CHECKING
/* Test for someone scribbling on unused space in chunk */ /* Test for someone scribbling on unused space in chunk */
if (chunk->requested_size < chunk->size) if (chunk->requested_size < chunk->size)
if (((char *) pointer)[chunk->requested_size] != 0x7E) if (!sentinel_ok(pointer, chunk->requested_size))
elog(WARNING, "detected write past chunk end in %s %p", elog(WARNING, "detected write past chunk end in %s %p",
set->header.name, chunk); set->header.name, chunk);
#endif #endif
...@@ -860,8 +888,7 @@ AllocSetFree(MemoryContext context, void *pointer) ...@@ -860,8 +888,7 @@ AllocSetFree(MemoryContext context, void *pointer)
else else
prevblock->next = block->next; prevblock->next = block->next;
#ifdef CLOBBER_FREED_MEMORY #ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */ wipe_mem(block, block->freeptr - ((char *) block));
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif #endif
free(block); free(block);
} }
...@@ -873,8 +900,7 @@ AllocSetFree(MemoryContext context, void *pointer) ...@@ -873,8 +900,7 @@ AllocSetFree(MemoryContext context, void *pointer)
chunk->aset = (void *) set->freelist[fidx]; chunk->aset = (void *) set->freelist[fidx];
#ifdef CLOBBER_FREED_MEMORY #ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */ wipe_mem(pointer, chunk->size);
memset(pointer, 0x7F, chunk->size);
#endif #endif
#ifdef MEMORY_CONTEXT_CHECKING #ifdef MEMORY_CONTEXT_CHECKING
...@@ -901,7 +927,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) ...@@ -901,7 +927,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
#ifdef MEMORY_CONTEXT_CHECKING #ifdef MEMORY_CONTEXT_CHECKING
/* Test for someone scribbling on unused space in chunk */ /* Test for someone scribbling on unused space in chunk */
if (chunk->requested_size < oldsize) if (chunk->requested_size < oldsize)
if (((char *) pointer)[chunk->requested_size] != 0x7E) if (!sentinel_ok(pointer, chunk->requested_size))
elog(WARNING, "detected write past chunk end in %s %p", elog(WARNING, "detected write past chunk end in %s %p",
set->header.name, chunk); set->header.name, chunk);
#endif #endif
...@@ -924,7 +950,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) ...@@ -924,7 +950,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
chunk->requested_size = size; chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */ /* set mark to catch clobber of "unused" space */
if (size < oldsize) if (size < oldsize)
((char *) pointer)[size] = 0x7E; set_sentinel(pointer, size);
#endif #endif
return pointer; return pointer;
} }
...@@ -987,7 +1013,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) ...@@ -987,7 +1013,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
chunk->requested_size = size; chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */ /* set mark to catch clobber of "unused" space */
if (size < chunk->size) if (size < chunk->size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E; set_sentinel(AllocChunkGetPointer(chunk), size);
#endif #endif
return AllocChunkGetPointer(chunk); return AllocChunkGetPointer(chunk);
...@@ -1136,11 +1162,9 @@ AllocSetCheck(MemoryContext context) ...@@ -1136,11 +1162,9 @@ AllocSetCheck(MemoryContext context)
AllocChunk chunk = (AllocChunk) bpoz; AllocChunk chunk = (AllocChunk) bpoz;
Size chsize, Size chsize,
dsize; dsize;
char *chdata_end;
chsize = chunk->size; /* aligned chunk size */ chsize = chunk->size; /* aligned chunk size */
dsize = chunk->requested_size; /* real data */ dsize = chunk->requested_size; /* real data */
chdata_end = ((char *) chunk) + (ALLOC_CHUNKHDRSZ + dsize);
/* /*
* Check chunk size * Check chunk size
...@@ -1170,7 +1194,8 @@ AllocSetCheck(MemoryContext context) ...@@ -1170,7 +1194,8 @@ AllocSetCheck(MemoryContext context)
/* /*
* Check for overwrite of "unallocated" space in chunk * Check for overwrite of "unallocated" space in chunk
*/ */
if (dsize > 0 && dsize < chsize && *chdata_end != 0x7E) if (dsize > 0 && dsize < chsize &&
!sentinel_ok(chunk, ALLOC_CHUNKHDRSZ + dsize))
elog(WARNING, "problem in alloc set %s: detected write past chunk end in block %p, chunk %p", elog(WARNING, "problem in alloc set %s: detected write past chunk end in block %p, chunk %p",
name, block, chunk); name, block, chunk);
......
...@@ -569,6 +569,8 @@ MemoryContextCreate(NodeTag tag, Size size, ...@@ -569,6 +569,8 @@ MemoryContextCreate(NodeTag tag, Size size,
void * void *
MemoryContextAlloc(MemoryContext context, Size size) MemoryContextAlloc(MemoryContext context, Size size)
{ {
void *ret;
AssertArg(MemoryContextIsValid(context)); AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size)) if (!AllocSizeIsValid(size))
...@@ -577,7 +579,9 @@ MemoryContextAlloc(MemoryContext context, Size size) ...@@ -577,7 +579,9 @@ MemoryContextAlloc(MemoryContext context, Size size)
context->isReset = false; context->isReset = false;
return (*context->methods->alloc) (context, size); ret = (*context->methods->alloc) (context, size);
return ret;
} }
/* /*
...@@ -638,6 +642,8 @@ void * ...@@ -638,6 +642,8 @@ void *
palloc(Size size) palloc(Size size)
{ {
/* duplicates MemoryContextAlloc to avoid increased overhead */ /* duplicates MemoryContextAlloc to avoid increased overhead */
void *ret;
AssertArg(MemoryContextIsValid(CurrentMemoryContext)); AssertArg(MemoryContextIsValid(CurrentMemoryContext));
if (!AllocSizeIsValid(size)) if (!AllocSizeIsValid(size))
...@@ -646,7 +652,9 @@ palloc(Size size) ...@@ -646,7 +652,9 @@ palloc(Size size)
CurrentMemoryContext->isReset = false; CurrentMemoryContext->isReset = false;
return (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
return ret;
} }
void * void *
...@@ -677,7 +685,7 @@ palloc0(Size size) ...@@ -677,7 +685,7 @@ palloc0(Size size)
void void
pfree(void *pointer) pfree(void *pointer)
{ {
StandardChunkHeader *header; MemoryContext context;
/* /*
* Try to detect bogus pointers handed to us, poorly though we can. * Try to detect bogus pointers handed to us, poorly though we can.
...@@ -690,12 +698,12 @@ pfree(void *pointer) ...@@ -690,12 +698,12 @@ pfree(void *pointer)
/* /*
* OK, it's probably safe to look at the chunk header. * OK, it's probably safe to look at the chunk header.
*/ */
header = (StandardChunkHeader *) context = ((StandardChunkHeader *)
((char *) pointer - STANDARDCHUNKHEADERSIZE); ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
AssertArg(MemoryContextIsValid(header->context)); AssertArg(MemoryContextIsValid(context));
(*header->context->methods->free_p) (header->context, pointer); (*context->methods->free_p) (context, pointer);
} }
/* /*
...@@ -705,7 +713,12 @@ pfree(void *pointer) ...@@ -705,7 +713,12 @@ pfree(void *pointer)
void * void *
repalloc(void *pointer, Size size) repalloc(void *pointer, Size size)
{ {
StandardChunkHeader *header; MemoryContext context;
void *ret;
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %lu",
(unsigned long) size);
/* /*
* Try to detect bogus pointers handed to us, poorly though we can. * Try to detect bogus pointers handed to us, poorly though we can.
...@@ -718,20 +731,17 @@ repalloc(void *pointer, Size size) ...@@ -718,20 +731,17 @@ repalloc(void *pointer, Size size)
/* /*
* OK, it's probably safe to look at the chunk header. * OK, it's probably safe to look at the chunk header.
*/ */
header = (StandardChunkHeader *) context = ((StandardChunkHeader *)
((char *) pointer - STANDARDCHUNKHEADERSIZE); ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
AssertArg(MemoryContextIsValid(header->context)); AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %lu",
(unsigned long) size);
/* isReset must be false already */ /* isReset must be false already */
Assert(!header->context->isReset); Assert(!context->isReset);
ret = (*context->methods->realloc) (context, pointer, size);
return (*header->context->methods->realloc) (header->context, return ret;
pointer, size);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment