fredericgermain / leaktracer Goto Github PK
View Code? Open in Web Editor NEWContinuation of the LeakTracer project
Home Page: http://www.andreasen.org/LeakTracer/
License: GNU General Public License v2.0
Continuation of the LeakTracer project
Home Page: http://www.andreasen.org/LeakTracer/
License: GNU General Public License v2.0
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.)
Hello @fredericgermain,
First of all, thanks leaktracer.
This tool is a great help to me. simple and easy!
By the way,
Sometimes our 3rd party app with leaktracer received segmentation fault and die.
below is stack trace from our internal debugging daemon.
I never seen below functions, what's that?
Backtrace :
#1 [<b6f8d604>] (request_backtrace(int) + 0x230)
#2 [<b6f8d770>] (request_backtrace(int) + 0x39c)
#3 [<b68ca7e0>] (__default_sa_restorer_v2 + 0x0)
#4 [<b69ed73c>] (_Unwind_VRS_Pop + 0x50)
#5 [<b69edfd4>] (_Unwind_Backtrace + 0x414)
#6 [<b69ed67c>] (_Unwind_VRS_Set + 0x50c)
#7 [<b69ed298>] (_Unwind_VRS_Set + 0x128)
#8 [<b69edbd8>] (_Unwind_Backtrace + 0x18)
When I run app without it, everything is ok.
Any idea?
When execution sequence is:
->leaktracer_startMonitoringAllThreads()
->snd_pcm_open() or snd_mixer_attach()
->......
The program will deadlock.
When execution sequence is:
->snd_pcm_open() or snd_mixer_attach()
->leaktracer_startMonitoringAllThreads()
->......
The program run normally.
This happened while using log4cxx. I worked-around the issue by just turning off log4cxx. It was on an old version of LeakTracer too so maybe it's been fixed since then. Maybe a recursive mutex or semaphore would fix the issue if not.
Apologies for misplacing the message here (I couldn't find an email), but I saw you have been working in Rust for a while. I have been working on Rust dev productivity tooling, and have modified the compiler for sizable (up to 40%) speed-ups in incremental build time. https://www.coderemote.dev/blog/faster-rust-compiler-macro-expansion-caching/
Would love to chat!
Hi,
I use dlsym(RTLD_NEXT) instead of using unambiguous function name like "__libc_malloc".
But it seems to be deadlock durring lib link.
show the gdb backtrace:
(gdb) bt
#0 pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:94
#1 0x00007f2bbf265c57 in leaktracer::MemoryTrace::Setup() () from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
#2 0x00007f2bbf2655e9 in calloc () from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
#3 0x00007f2bbe30d690 in _dlerror_run (operate=operate@entry=0x7f2bbe30d130 <dlsym_doit>, args=args@entry=0x7fff6832b590) at dlerror.c:141
#4 0x00007f2bbe30d198 in __dlsym (handle=, name=) at dlsym.c:70
#5 0x00007f2bbf2659df in leaktracer::MemoryTrace::init_no_alloc_allowed() ()
from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
#6 0x00007f2bbf050a80 in pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:103
#7 0x00007f2bbf265c57 in leaktracer::MemoryTrace::Setup() () from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
#8 0x00007f2bbf264de9 in malloc () from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
#9 0x00007f2bbed6d566 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007f2bbf4fa1da in call_init (l=, argc=argc@entry=1, argv=argv@entry=0x7fff6832b6b8, env=env@entry=0x7fff6832b6c8)
at dl-init.c:78
#11 0x00007f2bbf4fa2c3 in call_init (env=, argv=, argc=, l=) at dl-init.c:36
#12 _dl_init (main_map=0x7f2bbf70e1c8, argc=1, argv=0x7fff6832b6b8, env=0x7fff6832b6c8) at dl-init.c:126
#13 0x00007f2bbf4eb29a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#14 0x0000000000000001 in ?? ()
#15 0x00007fff6832c825 in ?? ()
#16 0x0000000000000000 in ?? ()
lib link as below:
Reading symbols from test...done.
Attaching to program: /root/LeakTracer/LeakTracer/tests/test, process 26911
Reading symbols from /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so...(no debugging symbols found)...done.
Loaded symbols for /root/LeakTracer/LeakTracer/build/x86_64-linux-gnu/4.8/libleaktracer.so
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libpthread-2.19.so...done.
done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/x86_64-linux-gnu/libpthread.so.0
Reading symbols from /usr/lib/x86_64-linux-gnu/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/x86_64-linux-gnu/libstdc++.so.6
Reading symbols from /lib/x86_64-linux-gnu/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libgcc_s.so.1
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/librt-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/librt.so.1
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libdl-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libdl.so.2
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libm-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libm.so.6
pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:94
94 ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S: No such file or directory.
It seems that malloc happens before completed lib link, and _dlerror_run when trying dlysm. But _dlerror_run need to calloc, so deadlock happens.
Any advise? I use test.cc as the demo.
(master)$ make
g++ -Ilibleaktracer/include -Ilibleaktracer/src -DUSE_BACKTRACE -Wall -pthread -O3 -finline-limit=10000 -c -o /home/skoblins/workspace/LeakTracer/build/x86_64-pc-linux-gnu/4.7.3/AllocationHandlers.o libleaktracer/src/AllocationHandlers.cpp
In file included from libleaktracer/src/AllocationHandlers.cpp:14:0:
libleaktracer/include/MemoryTrace.hpp: In member function ‘bool leaktracer::MemoryTrace::AllMonitoringIsDisabled()’:
libleaktracer/include/MemoryTrace.hpp:110:8: error: ‘intptr_t’ was not declared in this scope
libleaktracer/include/MemoryTrace.hpp:110:17: error: expected ‘)’ before ‘pthread_getspecific’
libleaktracer/include/MemoryTrace.hpp:110:77: error: expected ‘)’ before ‘;’ token
libleaktracer/include/MemoryTrace.hpp:110:77: error: expected ‘)’ before ‘;’ token
libleaktracer/include/MemoryTrace.hpp: In member function ‘int leaktracer::MemoryTrace::InternalMonitoringDisablerThreadUp()’:
libleaktracer/include/MemoryTrace.hpp:114:3: error: ‘intptr_t’ was not declared in this scope
libleaktracer/include/MemoryTrace.hpp:114:12: error: expected ‘;’ before ‘oldvalue’
libleaktracer/include/MemoryTrace.hpp:115:3: error: ‘oldvalue’ was not declared in this scope
libleaktracer/include/MemoryTrace.hpp:115:24: error: expected ‘;’ before ‘pthread_getspecific’
libleaktracer/include/MemoryTrace.hpp: In member function ‘int leaktracer::MemoryTrace::InternalMonitoringDisablerThreadDown()’:
libleaktracer/include/MemoryTrace.hpp:122:3: error: ‘intptr_t’ was not declared in this scope
libleaktracer/include/MemoryTrace.hpp:122:12: error: expected ‘;’ before ‘oldvalue’
libleaktracer/include/MemoryTrace.hpp:123:3: error: ‘oldvalue’ was not declared in this scope
libleaktracer/include/MemoryTrace.hpp:123:24: error: expected ‘;’ before ‘pthread_getspecific’
libleaktracer/include/MemoryTrace.hpp: In member function ‘int leaktracer::MemoryTrace::InternalMonitoringDisablerThreadUp()’:
libleaktracer/include/MemoryTrace.hpp:119:2: warning: control reaches end of non-void function [-Wreturn-type]
libleaktracer/include/MemoryTrace.hpp: In member function ‘int leaktracer::MemoryTrace::InternalMonitoringDisablerThreadDown()’:
libleaktracer/include/MemoryTrace.hpp:127:2: warning: control reaches end of non-void function [-Wreturn-type]
libleaktracer/include/MemoryTrace.hpp: In member function ‘bool leaktracer::MemoryTrace::AllMonitoringIsDisabled()’:
libleaktracer/include/MemoryTrace.hpp:111:2: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [/home/skoblins/workspace/LeakTracer/build/x86_64-pc-linux-gnu/4.7.3/AllocationHandlers.o] Error 1
Hi,
What version of gcc is LeakTracer compatible with? When running it against programs compiled with gcc 4.8.2 I see the following warnings during the analyzing step
(copying example warnings)
During symbol reading, unsupported tag: 'DW_TAG_GNU_template_parameter_pack'.
During symbol reading, unexpected tag in read_type_die: 'DW_TAG_rvalue_reference_type'.
During symbol reading, cannot get low and high bounds for subprogram DIE at 568036.
on centos 7.2, I find Xorg have bugs about mem leaks.
but by using leaktracer, the /usr/bin/Xorg start successfuly. but it doesn't functions normally, I cannot see the login screen.
steps:
rename the Xorg to /usr/bin/Xorg-real
new a shell file /usr/bin/Xorg:
"
export LD_PRELOAD=/home/zoge/workfolder/leaktracer/libleaktracer.so
export LEAKTRACER_ONSIG_STARTALLTHREAD=USR1
export LEAKTRACER_ONSIG_REPORT=USR2
export LEAKTRACER_ONSIG_REPORTFILENAME=/home/zoge/workfolder/leaktracer/leaks.out
exec /usr/bin/Xorg-real $*
"
last systemctl start gdm.
the /usr/bin/Xorg-real started successfully, but I cannot see the login screen.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.