Tracing memory allocations
Tracing is when instead of stopping when a function is called a tool will simply write a log line (usually with some additional data). Tracing is often a lot faster than interrupting the execution and yielding control to a user to handle the break point.
This is probably the simplest solution for you. You could trace all allocations either using a debugger with tracing or scripting capabilities or using a specific tracing utility such as ltrace
.
Once you have tracing set-up and running, you can search for the address of the allocated buffer you're interested in investigating, to find all calls it was involved in.
The ltrace
man page is quite helpful but in your case simply grep
-ing for the address will do just fine. ltrace
has definitions for standard library APIs such as new
and malloc
.
Tracing with gdb
will require a bit of gdb-scripting but something like the following should do:
(gdb) b malloc
Breakpoint 1 at XXXX
(gdb) commands 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>silent # don't stop on breakpoint being hit
>backtrace # print current back-trace
>p $eax # Pass the input to the call, should be the size allocation!
>fin # execute till function's return
>p $eax # print return value, should be chunk address!
>continue # continue execution of the program
>end
Memory access break point on the allocated region
Using a debugger such as gdb
, you could place a memory access breakpoint (also called a watchpoint) on the allocation's address. Thus by executing awatch <allocation address>
you'll have a breakpoint hit every time the allocation is accessed (there's a caveat, though).
This won't immediately give you the size of the allocation, but with some reverse engineering and back-tracking the address's origin, you can find the original allocation call that resulted in that buffer. A beneficial side-effect is easily seeing what's the allocation used for.
As mentioned previously using memory breakpoints may have a caveat. If your hardware doesn't support the mechanisms required for implementing memory breakpoints efficiently, memory break points may be implemented in software which is pretty slow.
Looking up the size through heap data structures
This may be the most straight-forward way to answer your original question (how to find the size of an allocated heap chunk) theoretically but the most difficult to implement. It may still be of interest to future readers.
As the heap is designed to manage allocations in different sizes, all heap implementations maintain metadata about the size of all allocated chunks. That metadata can be read or retrieved and heap-visualization tools will even help with that.
Some heap implementations hold the chunk metadata in-bounds, and prefix each allocated chunk with a short header that either directly indicates of it's size, or points to a "bin" of allocations of a given size, or both. dlmalloc is an example of such implementation.
Some heap allocator implementations include:
dlmalloc - Doug Lea's malloc
jemalloc - Jason Evans' malloc
HeapAlloc - Visual Studio's allocator
Side note: heap allocations don't necessarily originate from new
calls. There are other possible APIs that request memory from the heap, malloc
for example. You should find the lowest API that might interest you.