memory leak detection using dbx

The Solaris compiler suite ships with dbx, a source level debugger. Later versions include additional functionality to detect memory leaks and dangling blocks at program exit. The Sun guys once again designed a pretty powerful tool with a god awful interface. Here are some hints to using the detector.

Suppose you have a simple program like this, which is both leaking memory and has open blocks at program exit:

int main(int argc, char *argv[]) {
char *openBlock = new char[255];

for(int i=0; i &lt 100; ++i) {
char *leak = new char[i * 1024];
sleep(5);
}
}

It’s pretty obvious just looking at this code that we’re leaking a lot of memory; leaving a lot of dangling pointers, etc. Unfortunately most code in the real world is not this obvious. Sometimes it takes a little extra help to track down the leaks. This is especially true when you’re trying to track down a leak in legacy code. There’s often a ton of cruft in the way, making detecting the leak visually that much more difficult.

Fortunately, dbx comes to our rescue. There are a number of dbx commands to control run time checking. Here’s a quick run down of the common ones:

check memusage – enables memory leak detection and memory usage summary reports at program exit.

showleaks – show memory leaks when you’ve stopped at a breakpoint.

showmemuse – show the memory usage report when you’ve stopped at a breakpoint.

dbxenv rtc_mel_at_exit – controls the verbosity of the memory usage report at the end of execution. I use “verbose” most of the time.

dbxenv rtc_error_log_file_name – lets you specify where you want the summary report written.

We run the above program in dbx as follows:

bash-4.1$ dbx a.out
(dbx) check -memuse
(dbx) dbxenv rtc_mel_at_exit verbose
(dbx) dbxenv rtc_error_log_file_name a.out.errors
(dbx) run
Running: a.out
(process id 10331)
Reading librtc.so
RTC: Enabling Error Checking...
RTC: Running program...
Checking for memory leaks...

Actual leaks report (actual leaks: 97 total size: 4842752 bytes)

Memory Leak (mel):
Found 96 leaked blocks with total size 4842497 bytes
At time of each allocation, the call stack was:
[1] operator new() at 0xfd5061ac
[2] main() at line 7 in "main.cpp"

Memory Leak (mel):
Found leaked block of size 255 bytes at address 0x20be8
At time of allocation, the call stack was:
[1] operator new() at 0xfd5061ac
[2] main() at line 4 in "main.cpp"

Pretty nice. Not as nice as a purify run, and certainly not as intuitive, but it gets the job done without having to fork over the $$$ for a purify license.

Tagged with: , ,
Posted in Uncategorized
Design a site like this with WordPress.com
Get started