diff options
| author | svn2git <svn2git@FreeBSD.org> | 1994-07-01 08:00:00 +0000 |
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1994-07-01 08:00:00 +0000 |
| commit | 5e0e9b99dc3fc0ecd49d929db0d57c784b66f481 (patch) | |
| tree | e779b5a6edddbb949b7990751b12d6f25304ba86 /lib/libmalloc/dumpheap.c | |
| parent | a16f65c7d117419bd266c28a1901ef129a337569 (diff) | |
Diffstat (limited to 'lib/libmalloc/dumpheap.c')
| -rw-r--r-- | lib/libmalloc/dumpheap.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/libmalloc/dumpheap.c b/lib/libmalloc/dumpheap.c new file mode 100644 index 000000000000..e75ba8e8f279 --- /dev/null +++ b/lib/libmalloc/dumpheap.c @@ -0,0 +1,107 @@ +/* Author: Mark Moraes <moraes@csri.toronto.edu> */ + +/*LINTLIBRARY*/ + +#include "defs.h" +#include "globals.h" + +RCSID("$Id: dumpheap.c,v 1.1 1994/03/06 22:59:30 nate Exp $") + +/* + * Same as malloc_verify except that it prints the heap as it goes + * along. Some would argue that the printout routine should not have + * the ASSERTS, and should print a corrupt heap as well. + * Unfortunately, if any of those ASSERTs is false, this routine could + * wander off into the sunset because of corrupt tags. I have relaxed + * the tests for free list pointers because this routine doesn't need + * them so it just whines + */ +void +mal_heapdump(fd) +FILE *fd; +{ + REGISTER Word *ptr; + REGISTER Word *blk; + REGISTER Word *blkend; + char buf[512]; /* long enough for the sprintfs below */ + + if (_malloc_loword == NULL) { /* Nothing malloc'ed yet */ + (void) fputs("Null heap - nothing malloc'ed yet\n", fd); + return; + } + + (void) fputs("Heap printout:\n", fd); + (void) sprintf(buf, "Rover pointer is 0x%lx\n", (ulong) _malloc_rover); + (void) fputs(buf, fd); + if(!(_malloc_rover == NULL + || PTR_IN_HEAP(_malloc_rover) + || VALID_END_SIZE_FIELD(_malloc_rover) + || VALID_NEXT_PTR(_malloc_rover) + || VALID_PREV_PTR(_malloc_rover))) + (void) fputs("corrupt Rover pointer\n", fd); + for(ptr = _malloc_mem; ptr != NULL; ptr = ptr->next) { + /* print the arena */ + (void) sprintf(buf, "Arena from 0x%lx to 0x%lx, %lu (0x%lx) words\n", + (ulong) ptr, (ulong) (ptr + SIZE(ptr+1)), + (ulong) SIZE(ptr+1)+1, (ulong) SIZE(ptr+1)+1); + (void) fputs(buf, fd); + (void) sprintf(buf, "Next arena is 0x%lx\n", (ulong)ptr->next); + (void) fputs(buf, fd); + (void) fflush(fd); + ASSERT(SIZEFIELD(ptr+1) == SIZEFIELD(ptr + SIZE(ptr+1)), + "corrupt malloc arena"); + blkend = ptr + SIZE(ptr + 1); + for(blk = ptr + ARENASTART; blk < blkend; blk += SIZE(blk)) { + (void) sprintf(buf, " %s blk: 0x%lx to 0x%lx, %lu (0x%lx) words", + TAG(blk) == FREE ? "Free" : "Allocated", + (ulong) blk, (ulong) (blk+SIZE(blk)-1), + (ulong) SIZE(blk), (ulong) SIZE(blk)); + (void) fputs(buf, fd); + (void) fflush(fd); + ASSERT(PTR_IN_HEAP(blk), "corrupt pointer encountered"); + if (TAG(blk) == FREE) { + int i, n; + char *cp; + + (void) sprintf(buf, " next=0x%lx, prev=0x%lx\n", + (ulong) NEXT(blk + FREESIZE(blk) - 1), + (ulong) PREV(blk + FREESIZE(blk) - 1)); + (void) fputs(buf, fd); + /* Make sure free block is filled with FREEMAGIC */ + n = (SIZE(blk) - FREE_OVERHEAD) * + sizeof(Word); + cp = (char *) (blk + FREEHEADERWORDS); +#ifdef DEBUG + for (i = 0; i < n; i++, cp++) { + if (*cp != FREEMAGIC) { + (void) fputs( + " ** free block changed after being freed.\n", fd); + break; + } + } +#endif + } else { +#ifdef DEBUG + (void) sprintf(buf, " really %lu bytes\n", (ulong) REALSIZE(blk)); + (void) fputs(buf, fd); +#else + (void) fputs("\n", fd); +#endif + } + (void) fflush(fd); + ASSERT(VALID_START_SIZE_FIELD(blk), + "corrupt SIZE field encountered in mal_dumpheap()"); + if (TAG(blk) == FREE) { + if( ! VALID_NEXT_PTR(blk + FREESIZE(blk) - 1)) + (void) fputs(" ** bad next pointer\n", fd); + if( ! VALID_PREV_PTR(blk + FREESIZE(blk) - 1)) + (void) fputs(" ** bad prev pointer\n", fd); + } else { + if ( ! VALID_MAGIC(blk)) + (void) fputs(" ** end of block overwritten\n", fd); + } + } + } + (void) fputs("==============\n", fd); + (void) fflush(fd); +} |
