HP-UX HB v13.00 Ch-11 - Software Development

HP-UX Handbook Rev 13.00 Page 88 (of 101)
Chapter 11 Software Development
October 29, 2013
This is even harder to track down than unchecked allocation failures, because again the abort
does not occur when overwriting the heap structures, but only on one of the next calls to
malloc() or free(). Also, the overwriting could have happened everywhere in the code,
whenever the program accesses the heap. There is no special function call to look for.
WDB’s heap checking features can help here. When switching on the heap checking, it inserts
wrappers for the libc allocation functions. Whenever a buffer is allocated, the wrappers will
allocate a few more bytes, and insert a bit pattern at the beginning and the end of the block.
When the buffer is freed, the wrappers check if the patterns are intact, and if not, tell you the
stack trace where the buffer has been allocated:
(gdb) set heap-check on
(gdb) run
Starting program: /space/mstreibe/cases/heap/a.out
warning: Memory block (size = 10 address = 0x7dff2470) appears to be
corrupted at the end.
Likely block allocation context is
#1 main() at x.c:10
#2 _start() from /usr/lib/libc.2
#3 _start() at ../../../Src/gnu/gdb/infrtc.c:2632
#4 $START$() from
warning: Use command backtrace (bt) to see the current context.
Ignore top 3 frames belonging to leak detection library of gdb
(gdb)
Here the buffer had a size of 10 bytes and was allocated in main(), line 10 of source file x.c.
In a second step we can make gdb stop the program when malloc() returns the address of the
buffer that gets its borders overwritten:
(gdb) bt
#0 __rtc_event () at ../../../Src/gnu/gdb/infrtc.c:699
#1 0x7de927b0 in check_bounds (pointer=0x4042c448, size=10,
pclist=0x40407454) at ../../../Src/gnu/gdb/infrtc.c:759
#2 0x7de93d50 in rtc_record_free (pointer=0x4042c448,
free_the_block=1) at ../../../Src/gnu/gdb/infrtc.c:1566
#3 0x7de94908 in __rtc_free (pointer=0x4042c448 "1234567890") at
../../../Src/gnu/gdb/infrtc.c:1932
#4 0x2ab8 in main (argc=2, argv=0x7dff0ad4) at x.c:14
#5 0x7def79e4 in _start+0xc8 () from /usr/lib/libc.2
(gdb) frame 4 go to main()
#4 0x2ab8 in main (argc=2, argv=0x7dff0ad4) at x.c:14
14 free(p[i]);
(gdb) print p[i] print the buffer address
$1 = 0x4042c448 "1234567890"
(gdb) set heap-check watch 0x4042c448 watch the address