Section 7.3. Finding Memory Leaks with mpr

   


7.3. Finding Memory Leaks with mpr

The mtrace() facility in glibc is good, but the mpr memory allocation profiler[2] is in some ways easier to use and has some more sophisticated scripts for processing its logfile output.

[2] Available from http://www3.telus.net/taj_khattra/mpr.html as well as with many Linux distributions.

The first step in using mpr (after building the code with debug information enabled[3])is to set an environment variable, MPRFI, that tells mpr what command it should pipe the log through (if it is not set, no log is generated). For small programs, MPRFI should be set to something like cat > mpr.log. For larger programs, it can save a significant amount of space to compress the log file while writing it by setting MPRFI to gzip -1 >mpr.log.gz.

[3] For portability, most of the mpr log analysis tools use gdb to relate addresses to their location in the source code. For this to work, the program must include debugging information.

The easiest way to do this is to use the mpr script to run your program; if MPRFI is not already set, it sets MPRFI to gzip -1 >log.%p.gz, which creates a logfile with the process ID of the program being debugged and preloads the mpr library so that you do not have to rebuild your program at all. Here is what we did to create a log file for a fixed version of our test program:

 $ MPRFI="cat >mpr.log" mpr ./broken 1: 12345 2: 12345678 3: 12345678 4: 12345 5: 12345 6: 12345 7: 12345 $ ls -l mpr.log -rw-rw-r--   1 ewt         ewt          142 May 17 16:22 mpr.log 


Once the log file has been created, there are a number of tools available for analyzing it. All of these programs expect an mpr log on standard input. If the output from these tools has numbers where you expect function names (probably with a warning like "cannot map pc to name"), the problem may be the version of the awk utility that mpr is using. The mpr documentation suggests exporting the MPRAWK environment variable to choose the mawk version of awk for best results: export MPRAWK='mawk -W sprintf=4096'. In addition, the stack randomization provided by the kernel "Exec-shield" functionality can confuse mpr; you can ameliorate this by using the setarch command to disable Exec-shield while running the program under investigation and while running the mpr filters: for example, setarch i386 mpr program and setarch i386 mprmap ....

You may still end up with a few stack frames that mpr cannot find a textual symbol name for; you can generally ignore them.

mprmap program

This converts the program addresses in an mpr log into function names and source code locations. The executable file name that generated the log must be given as an argument. To see all the allocations that occurred in a program, along with the function call chain that led to the allocations, you could use mprmap program < mpr.log. By default, this program displays the function name. Using the -f flag causes it to display the file names, as well, and -l displays the line number within the file. The -l argument implies the -f argument.

 

The output of this program is considered a valid mpr log file, and as such it can be piped through any of the other mpr utility programs.

mprchain

This converts the log into output grouped by call chain. A function call chain is a list of all the functions that are currently active at some point in a program. For example, if main() calls getargs(), which then calls parsearg(), the active call chain while parsearg() is running is displayed as main:getargs:parsearg. For each unique call chain that allocated memory during a program's execution, mprchain displays the number of allocations made by that chain[4] and the total bytes allocated by that chain.

mprleak

This filter examines the log file for all of the allocated regions that were never freed. A new log file, which consists of only those allocations that caused leaks, is generated on standard out.

 

The output of this program is considered a valid mpr log file, and as such it can be piped through any of the other mpr utility programs.

mprsize

This filter sorts memory allocations by size. To see memory leaks by size, use the output from mprleak as the input to mprsize.

mprhisto

Displays a memory allocation histogram.


[4] More specifically, it is the sum of all the allocations made by the final function in the chain when it was invoked through that particular chain.

Now that we know about the log analyzers, it is easy to find the memory leak in our test program: Merely use the command mprleak mpr.log | mprmap -l ./broken (which is equivalent to mprmap -l ./broken mpr.log | mprleak) to find the memory leak on line 20.

 $ mprleak mpr.log | mprmap -l ./broken m:broken(broken.c,20):main(broken.c,47):5:134518624 



       
    top
     


    Linux Application Development
    Linux Application Development (paperback) (2nd Edition)
    ISBN: 0321563220
    EAN: 2147483647
    Year: 2003
    Pages: 168

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net