-
Notifications
You must be signed in to change notification settings - Fork 120
/
README
185 lines (126 loc) · 6.98 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
Library: LeakTracer
Homepage: http://www.andreasen.org/LeakTracer/
Maintainer: Frederic GERMAIN
Bug reports: https://github.com/fredericgermain/LeakTracer/issues
License (library): LGPLv2.1+
License (manual and tools): GPLv2+
General Information
===================
This library is designed to be a nice complement of valgrind and libduma (ex efence) to
detect leak memory. It simply override C/C++ allocation function (new, malloc, ...) to
keep then in a simple list that could be analysed later. The effective allocation is
still done by the underlying libc.
It can be used when valgrind is not ported on your platform, when libduma is using too
much virtual memory (embedded system), or when you're really interested in tracking only
memory leaks.
You may start/stop/dump monitoring allocation from the first allocation, when the program
receive a signal (for ex. SIGUSR1), or when you explicitly call a LeakTracer function.
The following documentation is inspired by DUMA, which is quite similar to use.
Installation
============
See the file 'INSTALL'
Usage
=====
3 ways to load the libleaktracer library :
* Link your program with libleaktracer.a
* Link your program with libleaktracer.so. You need the option -lleaktracer to be the
first of your link command. You should see leaktracer.so as the first NEEDED entry of
the Dynamic Section when you do a "objdump -p" of your program (through this check is
really dependent of your binary loader)
* use the LD_PRELOAD environment variable to be sure it is loaded before any other library.
You don't need to change your program using this method. You can then customize LeakTracer
behaviour using Environment variables.
In any case your application must also be compiled with debugging symbols enabled
(i.e. -g), so that you can lookup part of code that leaked with your source code.
Environment variables
=====================
LeakTracer has several configuration switches that can be enabled via
the shell environment. These switches change how LeakTracer will behave, so
it's important to know them.
LEAKTRACER_NOBANNER - Prevent LeakTracer to announce itself on stderr when it load.
LEAKTRACER_ONSIG_STARTALLTHREAD - If set, install a signal handler that will start allocation
monitoring on the threads.
Supported value are SIGUSR1, SIGUSR2 or a signal number for now.
LEAKTRACER_ONSIG_STOPALLTHREAD - If set, install a signal handler that will stop allocation
monitoring on the threads.
Supported value are SIGUSR1, SIGUSR2 or a signal number for now.
LEAKTRACER_ONSIG_REPORT - If set, install a signal handler that will write a raw LeakTracer
report in the file LEAKTRACER_ONSIG_REPORTFILENAME.
Supported value are SIGUSR1, SIGUSR2 or a signal number for now.
LEAKTRACER_ONSIG_REPORTFILENAME - Name of a file where a report will be dump on a LEAKTRACER_ONSIG_REPORT.
LEAKTRACER_ONSTART_STARTALLTHREAD - If set, start monitoring all allocation from the first allocation made.
LEAKTRACER_ONEXIT_REPORT - If set, write a raw LeakTracer report in the file
LEAKTRACER_ONEXIT_REPORTFILENAME when program exit.
LEAKTRACER_ONEXIT_REPORTFILENAME -
LEAKTRACER_AUTO_REPORTFILENAME - Equivalent to LEAKTRACER_ONSTART_STARTALLTHREAD=1
LEAKTRACER_ONEXIT_REPORT=1 LEAKTRACER_ONEXIT_REPORTFILENAME=$LEAKTRACER_AUTO_REPORTFILENAME
LEAKTRACER_EXIT_CODE_ON_LEAKS - The program will exit with specified code if at least one leak is present.
Example:
LD_PRELOAD=/usr/lib/libleaktracer.so LEAKTRACER_AUTO_REPORTFILENAME=leaks.out /bin/ls
LD_PRELOAD=/usr/lib/libleaktracer.so LEAKTRACER_ONSIG_STARTALLTHREAD=USR1 LEAKTRACER_ONSIG_REPORT=USR2 LEAKTRACER_ONSIG_REPORTFILENAME=leaks.out top
killall -USR1 top
...
killall -USR2 top
Sometimes, SIGUSR1 and SIGUSR2 are used. You can use RT signals, which are generally not used :
LD_PRELOAD=/usr/lib/libleaktracer.so LEAKTRACER_ONSIG_STARTALLTHREAD=35 LEAKTRACER_ONSIG_REPORT=36 LEAKTRACER_ONSIG_REPORTFILENAME=leaks.out top
Fine grained control of memory allocation
=========================================
You can use directly LeakTracer api to start/stop allocation monitoring, or to write reports to file.
Two set of API are available, one in C, one in C++
C API
You should include file "leaktracer.h" in your program
C++ API
You should include file "MemoryTrace.hpp" in your program
Catching the leak
=================
Once you have your leak report, find the call stacks which generate the leaks.
The call stack is sequence of call where the leak appeared.
To find the code that generate the leak given a memory address, several method can be used.
* GDB/GDBSERVER: the most reliable method is to attach gdb or gdbserver to your program. When you're
attach, type "break *addr" or "disassemble addr addr+10" to know where the leak appeared.
The advantage of using a breakpoint is that you can find quickly how the leak happens.
* You can activate the core dump support using "ulimit -c unlimited" in your shell. Generate a corefile
with "kill -QUIT $pidprogram", and use gdb again to find the code that leak.
* addr2line utility can give you an address given a program. But if your leak appear in a dynamic library,
it won't give you the information.
Analyzing output
================
You should then run leak-analyze, since looking at the raw leaks.out file will
not help you much. You need perl to run it.
Two versions of lead-analyze are provided:
* one is using gdb to find the line of the leak in your source code. This is the best way so far.
* one is using addr2line. To problem with is method is that it won't find the line in the dynamic libraries
Help developping Leaktracer
=========================
You can use the debug mode to track problem in LeakTracer
To do that, build in debug mode :
> make DEBUG=1 clean all
> gdb /bin/ls
In gdb
set environment LD_PRELOAD /usr/lib/libleaktracer.so
set environment LEAKTRACER_AUTO_REPORTFILENAME leaks.out
run
...
Note about implementation
=========================
* FG: I tried to first use LTS variable instead of pthread_key, but it looks like I was having a problem with them
on a old uclibc problem.
* On x86_64, gcc 4.5.2, or other platform, it looks like there is a crash in __builtin_frame_address(i) if i > 1. You should define
ALLOCATION_STACK_DEPTH to 1, or define USE_BACKTRACE to use backtrace() function.
Project history
===============
Original project is made by Erwin S. Andreasen
Michael Gopshtein rewrite most of it to add nice start/stop and other functionalities.
Frederic Germain added malloc/realloc/free support, and environment variable support to
use LeakTracer without having to recompile your program.
License was change to LGPL/GPL from version 3.0.
If you're a original contributor and you have something to oppose to the license change, please contact
me, I'll rewrite some code.
Contact
=======
For any questions/problems/suggestions please contact
Frederic Germain, [email protected]
Patches you want to be integrated
=================================
Use github to submit your patches. Git way to do it are preferred.
Patches should be in unified diff form. (The -up option to GNU diff.)