diff options
author | Simon Howard | 2015-04-26 21:19:40 -0400 |
---|---|---|
committer | Simon Howard | 2015-04-26 21:19:40 -0400 |
commit | 31c0b0c7e1e9340145e11866c74e20ceddae77f9 (patch) | |
tree | 64c2ad9282fb63783d7aa1ffd55b911a441e5e27 /src | |
parent | 3bed35a90afe33571048edff4b38db07138aaaed (diff) | |
download | chocolate-doom-31c0b0c7e1e9340145e11866c74e20ceddae77f9.tar.gz chocolate-doom-31c0b0c7e1e9340145e11866c74e20ceddae77f9.tar.bz2 chocolate-doom-31c0b0c7e1e9340145e11866c74e20ceddae77f9.zip |
zone: Add -zonescan parameter.
As further tooling to help debug bugs like #530, add a command line
parameter that will scan the zone heap every time a block of memory
is freed with Z_Free(), to detect dangling pointers to the freed
block.
Diffstat (limited to 'src')
-rw-r--r-- | src/z_zone.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/z_zone.c b/src/z_zone.c index 91f31fb2..311eff50 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -64,6 +64,7 @@ typedef struct static memzone_t *mainzone; static boolean zero_on_free; +static boolean scan_on_free; // @@ -120,12 +121,54 @@ void Z_Init (void) block->size = mainzone->size - sizeof(memzone_t); //! - // Zone memory debugging flag. If set, zero memory after it is freed + // Zone memory debugging flag. If set, memory is zeroed after it is freed // to deliberately break any code that attempts to use it after free. // zero_on_free = M_ParmExists("-zonezero"); + + //! + // Zone memory debugging flag. If set, each time memory is freed, the zone + // heap is scanned to look for remaining pointers to the freed block. + // + scan_on_free = M_ParmExists("-zonescan"); } +// Scan the zone heap for pointers within the specified range, and warn about +// any remaining pointers. +static void ScanForBlock(void *start, void *end) +{ + memblock_t *block; + void **mem; + int i, len, tag; + + block = mainzone->blocklist.next; + + while (block->next != &mainzone->blocklist) + { + tag = block->tag; + + if (tag == PU_STATIC || tag == PU_LEVEL || tag == PU_LEVSPEC) + { + // Scan for pointers on the assumption that pointers are aligned + // on word boundaries (word size depending on pointer size): + mem = (void **) ((byte *) block + sizeof(memblock_t)); + len = (block->size - sizeof(memblock_t)) / sizeof(void *); + + for (i = 0; i < len; ++i) + { + if (start <= mem[i] && mem[i] <= end) + { + fprintf(stderr, + "%p has dangling pointer into freed block " + "%p (%p -> %p)\n", + mem, start, &mem[i], mem[i]); + } + } + } + + block = block->next; + } +} // // Z_Free @@ -157,6 +200,11 @@ void Z_Free (void* ptr) { memset(ptr, 0, block->size - sizeof(memblock_t)); } + if (scan_on_free) + { + ScanForBlock(ptr, + (byte *) ptr + block->size - sizeof(memblock_t)); + } other = block->prev; |