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 program 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
---------------------------------------------------------------------------------------