mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
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.
This commit is contained in:
parent
1d96bb9602
commit
a855148a29
@ -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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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)
|
|||||||
|
|
||||||
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 *
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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);
|
||||||
|
|
||||||
return (*header->context->methods->realloc) (header->context,
|
ret = (*context->methods->realloc) (context, pointer, size);
|
||||||
pointer, size);
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user