Memprof usage document



Hi Owen,

I was using memprof sometime back but did not find any documentation on
it, to clarify doubts.

So, I thought, I would write a small document on its usage. I tried to
explains how to use it, understanding the output, different preferences
etc. Result is the attached document. 

If you feel its appropriate and good, please upload it in the memprof
site or commit it into source code location. If you have any comments on
it, I can incorporate them and send it back. 

Regards,
Narayana


                    Memprof Usage Document



Memprof is a tool used for profiling memory usage and finding memory leaks in an application.
Memprof works by pre-loading a library to override the C Library's memory allocation functions.
User need not recompile the program to use memprof. The tool is freely available for download
from http://www.gnome.org/projects/memprof/, or the latest sources can be checked out from
GNOME CVS at
cvs.gnome.org and the developer can build the tool from the sources. Memprof
works on i386 architectures only.


Features of memprof:

a) Generates a profile of which functions in the program have allocated memory, and how much
was allocated by each function and by the functions it calls.

b) Scans memory and finds blocks allocated but are no longer referenced.

c) Has a nice GUI front-end, which makes it relatively easy to use.


1. Using memprof


Steps in using memprof are:

a) Running a program with memprof
b) Collecting the profiling information
c) Analizing the profiling output


1. 1. Running a program with memprof

- Compile the program with debug flags. Compile dependant libraries also with debug option,
if required. If the program is compiled with debug option, the profiling output will show
information properly with source code also. For example,

    $ gcc -g -o test test.c


- Run the program with memprof. This can be done in the following two ways:

i) Launch memprof from command line with the program name as argument

    $ memprof ./test

ii) Launch memprof from command line and then select the program to be profiled by selecting
it from File->Run Program menu or by clicking on Run button on the toolbar. This launches a
run dialog (file selector dialog); select the p
rogram from the run dialog and execute it by clicking on
Execute button.


Note: Its not always required to compile the program with debug (-g) flags. Developers can
simply start running the program with memprof. But the output shown will not contain the
source code information. If developers want source code information then it is advisable
to re-compile the program with debug flags.

Note: Memprof takes various commandline options which can be seen by running
“memprof –help” on the commandline.


Profiling a program which takes arguments/parameters/options:

There could be a situation where the program to be profiled requires certain agruments/options
to be passed. Memprof supports this too. There are two ways to do this:


a) Run the program from comandline along with memprof, as shown below:

     $memprof <memprof-arg1> <memprof-arg2> -- ./memleak-test-prog <arg1> <arg2> <arg3>

First specify the arguments to memprof and then add “--” to indicate that there are no more memprof
arguments. Then specify the program and its arguments.


b) Launch run dialog and then select the program to be profiled and edit the command to pass the
commandline arguments in the comand entry.


1.2. Collecting the profiling output

Profiling information can be obtained for an application in different stages while its running, depending
on the requirements.

  • Let the program/application run for a specific time and take the profiling output

  • Or start the application and execute few functioalities of that application and take the output.
    Basically its profiling part of the code which executes for those functioalities.

When the application/program is executing, do,
a) Click on Profile button on the toolbar to see a profile of memory usage, and
b) Click on Leaks button on the toolbar to see a list of memory leaks.

If program is short lived and it exits immediately, we may not be able to collect the profiling information.
In that case add a sleep at the end of the main routine of the program and recompile it and profile
once again. This is not required if the program is a kind of daemon or a GUI application which will be
waiting in the main loop for inputs from the user.


The next section describes how to interpret the output.


1.3. Analizing the output

Memprof provides the following kinds of profiling output:

a) Memory Profiling Information
b) Memory Leaks, and
c) Memory allocation statistics


1.3.1. Memory Profile

Memory profile shows list of functions in the program which have allocated memory including the
ones which have memory leaks. It shows how much memory was allocated by each functions and by
the functions it calls. It also shows the memory allocations for each caller of a function.

Memory profile output can be collected by selecting the menu item Process->Generate profile or
by simply clicking on the Profile button on the application toolbar. The output is shown in the Profile
Tab in the lower half of the memprof application window. The left side pane of the profile section
shows list of functions involved in memory allocations. The right side pane of the profile section
shows callers and descendants of each function involved in memory allocation.

Each function involved in memory allocation shows two statistics wth respect to the amount of memory
allocated. They are Self and Total. "Self" means memory allocated by the function itself. "Total" means
memory allocated by the function plus all functions it calls.

This output can be saved into a text file for further analysis by clicking the Save button on the toolbar
or by selecting File->Save Profile menu item. The saved file actually shows the same profile information
in text format. For example, the output of profile information looks like this.

main

children:
_dl_check_map_versions@@GLIBC_PRIVATE: 63
read_write_operations: 2830
total: 2893
self: 0

inherited:
_dl_check_map_versions@@GLIBC_PRIVATE: 2893


read_write_operations
children:
_dl_check_map_versions@@GLIBC_PRIVATE: 2830
total: 2830
self: 0

inherited:
main: 2830


1.3.2. Memory Leaks

To get the memory leaks output, user has to click on Leaks button on toolbar or select menu item
Process->Generate Leaks Report. The output is shown in the Leaks Tab in the lower half of the memprof
application window. Leaks Tab has two panes. Upper pane shows list of all memory leaks with
address, leaked memory size and the call used to allocated the memory. The lower pane
"Stack Trace" shows the stack trace of the memory leak context, which is useful in debugging the issue.
If the program is compiled with debug compiler flag, the stack trace shows detailed information like
file name, function name, line number etc. from the source code.

Double click on a stack frame to view the source code (if built with debug flag) in an editor. By default
memprof opens the source code in emacsclient. If user wants to open the source code in a
different editor, then change the editor from Settings->Preferences->Leak Detection Options->Command
entry. After that, double clicking on a stack frame opens the source code in the prefered editor.

Memory leaks output can be saved into a text file for further analysis by clicking on Save button on the
toolbar or by selecting menu item File->Save Leak Info. The saved file actually shows the same
leaks information text format. For example, saved memory leak information for a file looks like this:

Leaked 0x804a228 (1063 bytes)
malloc(): /home/naren/HEAD/memprof/memintercept.c:88
__i686.get_pc_thunk.cx()
read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:31
main(): /home/naren/Personal/memprof/memleak-test.c:61
__i686.get_pc_thunk.cx()
_start(): ../sysdeps/i386/elf/start.S:83


1.3.3. Memory Allocation statistics

memprof also gives the 'current' number of allocations, number of bytes per allocation and total number
of bytes allocated. Current allocations do not include the ones, which were freed.

The memory allocation state is represented through colors on a progress bar (with a scale). Mapping of a
color and memory state is given below:

Yellow: Allocated

Blue: Allocated, used and freed

Red: Allocated but not freed i.e. leaked memory.

Length of each color band on the progress bar is proportional to the size of the memory in that state.


2. Memprof Options

Memprof provides various options which can be seen by running “memprof –help” on the commandline.

Profiling a mulpti process/ multi threaded program:

Memprof can profile multi process or multi threaded program. To make it work, we have to do the following.

a) >From commandline, run memprof with –follow-fork, --follow-exec commandline agruments. This makes
sure that memprof gives profile information for a mulpti process program. For example,

$ memprof –follow-fork –follow-exec <program-name>


b) Or from GUI, before running a program, enable follow fork and follow exec from Settings.


3. Case study

This section describes how memprof tool finds out memory profile, memory leaks while running a sample
program. The sample program just reads one input file, reads its contents and copies the contents to the
output file. In that process it has some memory leaks. Lets see how memprof finds those memory allocation
and leak details.


Sample Code:     

      1 /* The program tries to read the contents of a file and write the same
      2    into another files. In that process, it introduces some memory leaks
      3    to be identified by the tools like memprof.
      4 */
      5 #include <stdio.h>
      6 #include <errno.h>
      7 #include <string.h>
      8
      9 long int read_write_operations (char *infile, char *outfile)
     10 {
     11         char buf[1024];
     12         int res, len;
     13         static long int count;
     14         char *out_buf;
     15         FILE *fp_in, *fp_out;
     16
     17         fp_in = fopen (infile, "r");
     18         if (fp_in == NULL) {
     19                 printf ("Failed to open file: %s, error: %s\n", infile,  strerror (errno));
     20                 return 1;
     21         }
     22
     23         fp_out = fopen (outfile, "w+");
     24         if (fp_out == NULL) {
     25                 printf ("Failed to open file: %s, error: %s\n", outfile,  strerror (errno));
     26                 return 1;
     27         }
     28
     29         while ((len = fread(buf, 1, 1024, fp_in)) > 0) {
     30                 out_buf = strdup (buf);
     31                 if (out_buf) {
     32                         res = fwrite (out_buf, 1, len, fp_out);
     33                         if (res == 0) {
     34                                 printf ("Error writing into output file:  %s\n", strerror (errno));
     35                                 break;
     36                         }
     37                         count = count + len;
     38                 }
     39         }
     40
     41         return count;
     42 }
     43
     44 int main (int argc, char **argv)
     45 {
     46         char *infile, *outfile;
     47         long int count;
     48
     49         if (argc != 3) {
     50                 char *usage;
     51                 usage = strdup ("Usage: memleak-test <infile> <outfile>");
     52                 printf ("%s\n", usage);
     53                 return 1;
     54         }
     55
     56         infile = strdup (argv [1]);
     57         outfile = strdup (argv[2]);
     58
     59         count = read_write_operations (infile, outfile);
     60
     61         if (count == 0) {
     62                 printf ("There is an error in reading or writing\n");
     63                 return 1;
     64         }
     65
     66         printf ("Wrote %ld bytes into the outfile: %s\n", count, outfile );
     67
     68         sleep (300);
     69
     70         return 0;
     71 }


The program has the following memory allocations and memory leaks:

1. Line 53: Allocating for variable 'usage'
2. Line 56 for infile
3.
Line 57 for outfile
4.
Line 17 for fp_in file descriptor
5.
Line 23 for fp_out file descriptor
6.
Line 30

All the above instances have memory allocations and memory leaks. Lets see how memprof
tool detects them.


Steps:
a) Compile the program

    $ gcc -g -o memleak-test memleak-test.c

b) Run the program with memprof

    $ memprof ./memleak-test infile outfile

c) Checking for memory leaks


Clicking on the leaks button on the toolbar gives memory leaks in the program. The leaks information
can also be saved into a plain text file. The output from the leaks file is:

Leaked 0x804a610 (1063 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:30
        main(): /home/naren/Personal/memprof/memleak-test.c:59
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x804a1e0 (1063 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:30
        main(): /home/naren/Personal/memprof/memleak-test.c:59
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049db0 (1063 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:30
        main(): /home/naren/Personal/memprof/memleak-test.c:59
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049c48 (352 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:23
        main(): /home/naren/Personal/memprof/memleak-test.c:59
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049ae0 (352 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        read_write_operations(): /home/naren/Personal/memprof/memleak-test.c:17
        main(): /home/naren/Personal/memprof/memleak-test.c:59
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049aa8 (16 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        do_malloc(): /home/naren/HEAD/memprof/memintercept.c:65
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        main(): /home/naren/Personal/memprof/memleak-test.c:56
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049a90 (16 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        do_malloc(): /home/naren/HEAD/memprof/memintercept.c:65
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        main(): /home/naren/Personal/memprof/memleak-test.c:56
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

Leaked 0x8049a78 (16 bytes)
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        __i686.get_pc_thunk.cx()
        do_malloc(): /home/naren/HEAD/memprof/memintercept.c:65
        malloc(): /home/naren/HEAD/memprof/memintercept.c:88
        __i686.get_pc_thunk.cx()
        main(): /home/naren/Personal/memprof/memleak-test.c:56
        __i686.get_pc_thunk.cx()
        _start(): ../sysdeps/i386/elf/start.S:83

If you observe carefully, each of the memory leaks we have identified earlier, were captured by
memprof, as shown in the above output.



---------------------------------------------------------------------------------------
Version:     0.1
Author:      Narayana Pattipati
Email Id:    narayana pattipati wipro com
---------------------------------------------------------------------------------------


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]