Giter Site home page Giter Site logo

wubingzheng / memleax Goto Github PK

View Code? Open in Web Editor NEW
647.0 37.0 73.0 301 KB

debugs memory leak of running process. Not maintained anymore, try `libleak` please.

License: GNU General Public License v2.0

C 90.79% Roff 5.22% CMake 3.99%
memory-leak debugger

memleax's Introduction

memleax

memleax debugs memory leak of a running process by attaching it, without recompiling or restarting.

status

Because the debugging work depends on CPU architecture and OS heavily, and I test memleax only on several programs, and it is not used widely by now. So there must be bugs.

Some known bugs for debugging multi-thread program, #38 and #39.

Besides, I write a new tool libleak, which works by hooking memory functions by LD_PRELOAD. It's much simpler and has much less impact on performance. So I am not going to improve memleax. Try libleak please.

how it works

memleax debugs memory leak of a running process by attaching it. It hooks the target process's invocation of memory allocation and free, and reports the memory blocks which live long enough as memory leak, in real time. The default expire threshold is 10 seconds, however you should always set it by -e option according to your scenarios.

It is very convenient to use, and suitable for production environment. There is no need to recompile the program or restart the target process. You run memleax to monitor the target process, wait for the real-time memory leak report, and then kill it (e.g. by Ctrl-C) to stop monitoring.

memleax follows new threads, but not forked processes. If you want to debug multiple processes, just run multiple memleax.

performance impact

Because target process's each invocation of memory allocation and free makes a TRAP, the performance impact depends on the frequency of memory invocation in target process.

For example, it impacts lightly to nginx with HTTP, while heavily with HTTPS, because OpenSSL calls malloc() terribly.

difference from Valgrind

  • Valgrind starts target process, while memleax attaches to a running process;

  • Valgrind gives memory leak report after target process quits, while memleax reports in real time;

  • Valgrind reports all unfreed memory include program init, while memleax reports only after attaching, skipping the init phase;

  • Valgrind runs target process on its virtual CPU, which makes it slow. While memleax hooks memory APIs, which may be less slow if the target process call memory APIs not often.

  • Valgrind debugs kinds of memory bugs, while memleax is lightweight and only detects memory leak.

In summary, I think Valgrind is more powerful, while memleax is more convenient and suitable for production environment.

licence

GPLv2

OS-machine

  • GNU/Linux at x86 and x86_64, tested on CentOS 7.2 and Ubuntu 16.04
  • GNU/Linux at armv7 and aarch64, tested on Raspbian and pi64.
  • FreeBSD at i386 and amd64, tested on FreeBSD 10.3

NOTE: If memleax can not show function backtrace on GNU/Linux at aarch64, you could try to compile the target program with -funwind-tables flag of GCC.

install by package

There are DEB and RPM packages for releases.

For Arch Linux users, memleax is available in AUR. Thanks to jelly.

For FreeBSD users, memleax is available in FreeBSD Ports Collection. Thanks to tabrarg.

I tried to submit memleax to Fedora EPEL, but failed. Any help is welcomed.

build from source

The development packages of the following libraries are required:

  • libunwind
  • libelf
  • libdw or libdwarf. libdw is preferred. They are used to read dwarf debug-line information. If you do not have them neither, set --disable-debug_line to configure to disable it. As a result you will not see file name and line number in backtrace.

These packages may have different names in different distributions, such as libelf may names libelf, elfutils-libelf, or libelf1.

NOTE: On FreeBSD 10.3, there are built-in libelf and libdwarf already. However another libelf and libdwarf still can be installed by pkg. memleax works with built-in libelf and pkg libdwarf. So you should install libdwarf by pkg, and must not install libelf by pkg.

After all required libraries are installed, run

$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

usage

start

To debug a running process, run:

$ memleax [options] <target-pid>

then memleax begins to monitor the target process, and report memory leak in real time.

You should always set expire time by -e options according to your scenarios. For example, if you are debugging an HTTP server with keepalive, and there are connections last for more than 5 minutes, you should set -e 360 to cover it. If your program is expected to free every memory in 1 second, you should set -e 2 to get report in time.

wait and check the report

The memory blocks live longer than the threshold, are showed as:

CallStack[3]: memory expires with 101 bytes, backtrace:
    0x00007fd322bd8220  libc-2.17.so  malloc()+0
    0x000000000040084e  test  foo()+14  foo.c:12
    0x0000000000400875  test  bar()+37  bar.c:20
    0x0000000000400acb  test  main()+364  test.c:80

CallStack[3] is the ID of CallStack where memory leak happens.

The backtrace is showed only on the first time, while it only shows the ID and counter if expiring again:

CallStack[3]: memory expires with 101 bytes, 2 times again

If the expired memory block is freed later, it shows:

CallStack[6]: expired-memory frees after 10 seconds

If there are too many expired-memory-blocks are freed on one CallStack, this CallStack will not be showed again:

Warning: too many expired-free at CallStack[6]. will not show this CallStack later

When you think you have found the answer, stop the debug.

stop

memleax quits on:

  • you stop it, by Ctrl-C or kill,
  • the target process quits,
  • too many leaks at one CallStack (option -m), or
  • too many CallStacks with memory leak (option -c).

After quitting, it also gives statistics for the CallStacks with memory leak:

CallStack[3]: may-leak=20 (2020 bytes)
    expired=20 (2020 bytes), free_expired=0 (0 bytes)
    alloc=20 (2020 bytes), free=0 (0 bytes)
    freed memory live time: min=0 max=0 average=0
    un-freed memory live time: max=20
    0x00007fd322bd8220  libc-2.17.so  malloc()+0
    0x000000000040084e  test  foo()+14  foo.c:12
    0x0000000000400875  test  bar()+37  bar.c:20
    0x0000000000400acb  test  main()+364  test.c:80

memleax's People

Contributors

diciu avatar jwilk avatar morxa avatar phdm avatar sten0 avatar wubingzheng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memleax's Issues

Can't compile on CentOS 6.9

OS:
CentOS release 6.9 (Final)

Steps to reproduce:
wget https://github.com/WuBingzheng/memleax/archive/v1.1.1.zip
unzip v1.1.1.zip && cd memleax-1.1.1
./configure && make && make install

Output:
checking machine type...
checking OS type...
checking libraries...
checking libunwind...
checking libelf...
checking libdw...
libdw-devel is missing.
checking libdwarf...
generate Makefile...
done.
cc -DMLX_X86_64 -DMLX_LINUX -DMLX_WITH_LIBDWARF -I/usr/include/libdwarf/ -g -O2 -Wall -c -o breakpoint.o breakpoint.c
In file included from machines.h:4:0,
from breakpoint.c:15:
ptrace_utils.h: In function ‘ptrace_get_regs’:
ptrace_utils.h:35:9: error: ‘PTRACE_GETREGSET’ undeclared (first use in this function)
ptrace(PTRACE_GETREGSET, pid, (void *)regset, &ioVec);
^
ptrace_utils.h:35:9: note: each undeclared identifier is reported only once for each function it appears in
ptrace_utils.h: In function ‘ptrace_set_regs’:
ptrace_utils.h:47:9: error: ‘PTRACE_SETREGSET’ undeclared (first use in this function)
ptrace(PTRACE_SETREGSET, pid, (void *)regset, &ioVec);
^
make: *** [breakpoint.o] Error 1

Memleax detect overwhelming memory leak while running curl program

I have using memleax to attach my C application. My application has CURL with SSL for push notification. if i use valgrind for one time program, It did not detect any memory leak.

but if I attached program to memleax, It detect overwhelming memory leak and kill my program as well.

Scenario to trigger:

  1. Create a curl with SSL program with scanf hooking from start and end, attached pid to memleax.

memleax_issue.txt

Can I use this to free up leaked memory

Memleax helps finding leaked memory.
Will it be possible to free up the leaked memory if I invoke this tool from the target process probably in a different thread?
I may sound lame, please correct me.
Thanks.

Using too much memory

I'm trying to use memleax in an environment with only 4GB of ram.

Memleax is allocating about 2GB immediately upon launch, and is being killed by the OOM killer.

Why would Memleax need to allocate this much memory?

Can't get this to detect any leaks.

This is under 64-bit RedHat 6 (yes, I know it's old, but it's what I have). memleax sources were obtained from the downloadable .tar.gz.

Perhaps I'm misunderstanding how this is supposed to work, but memleax does not detect any leaks on a program that (1) waits for the user to attach memleax, (2) after memleax is attached, allocates memory that is never freed, (2) and sleeps 30 seconds. Even though the unfreed memory blocks are allocated after memleax is attached, nothing is ever reported:

$ memleax -e 2 24838
== Begin monitoring process 24838...

== Target process exit.
== No expired memory blocks.

Test code below. Use by:

  • Compile with g++ -g test.cc

  • Run ./a.out

  • In another window, attach memleakx to a.out.

  • Go back to the window where a.out is running, and press [Enter]. Once you do that, test memory blocks are allocated, and the program sleeps for 30 seconds.

  • memleax never reports any leaks, even though the blocks were allocated after memleax was attached, and live for more than the default 10 seconds.

Test code:

#include <cstdio>
#include <cstdlib>
#include <unistd.h>

class testclass {
public:
    int             a;
    int             b;

    testclass(void)
    {
        a = 0;
        b = 0;
    }
};


int main()
{
    testclass  *t;
    char       buf[1000];
    void       *m;

    // Wait for [Enter] to be pressed
    printf("Start? ");
    fflush(stdout);
    fgets(buf, sizeof(buf) - 1, stdin);

    printf("starting\n");
    t = new testclass();
    m = malloc(200);
    sleep(30);
    printf("done\n");
    return 0;
}

32-bit app crashes with segmentation fault on CentOS 7 x64

Hey, WuBingzheng!

Here's the reproduction steps:

  1. Build the attached test app.
  2. Launch the test app.
  3. Launch memleax -p <test app pid>
  4. Press Enter in the terminal where the test app runs.
  5. The test app crashes with a segfault.

System info:

$ uname -r
3.10.0-693.21.1.el7.x86_64

test.zip

Thanks for developing such an awesome app!

Opening this on behalf of my colleague, who doesn't speak English.

not found api: malloc

I am trying to profile a init.d daemon and am having issues. Of course, trying to run: memleax <pid> will not work. When I run as superuser i.e. sudo memleax <pid>, I get the following message:

not found api: malloc

Is this recoverable at all?

Script to mimic valgrind behaviour?

It is stated in docs that

Valgrind starts target process, while memleax attaches to a running process;

But what should I do if want to attach to process ASAP? Is there a standard approach for it?

I've tried something like that:

#!/bin/bash
$@ &
pid=$!
kill -s STOP $pid
memleax -m1 -e1 $pid
kill -s CONT $pid
wait $pid

But I've get either a segfault or the following error:
Error in open /proc/pid/maps: No such file or directory

centos 6x64 and 7x64

Can't compile under centos.

cmake reporting error:
None of the required 'libelf' found
Could not find libdw or libdwarf

but these libraries are installed:
yum install elfutils-libelf-devel
yum install libdwarf-devel

Read map

Hi,

memleax failed by exiting wiith read map error:

if (read(fd, ms->data, end - start) != end - start) {
    printf("Error: read map of %s\n", path);
    exit(6);
}

Cange it to:

if ( (readRet = read(fd, ms->data, end - start)) != end - start) {
printf("Error: read map of %s. read:%d should:%d errno:%d\n", path, readRet, end-start, errno);
// exit(6);
}

=> Error: read map of /lib/x86_64-linux-gnu/libgcc_s.so.1. read:90096 should:90112 errno:0

it seems that read() is returning less bytes than requested.
So I commented the exit points and it works.
Maybe you have time to investigate why this is happening.

Regards,
Catalin,.

[fix failure to find libunwind on armhf] switch to cmake or autotools

Hi!

While investigating why Debian builds were failing for armhf and finding that libunwind wasn't being correctly detected, several people advised me to add either autotools or cmake support to memleax and to drop the hand-written configure. Have you already tried either of these, is there one you would prefer, and are you interested in adding the support yourself or would you like me to learn how to do this?

Sincerely,
Nicholas

https://tests.reproducible-builds.org/debian/rb-pkg/unstable/armhf/memleax.html

Include CMakeLists.txt in tar.gz release file

While working in including memleax in Fedora repository, I noticed that
CMakeLists.txt included in master branch, is not included in tar.gz release file.
The tar.gz release file only contains configure.ac, that is not included in master branch.
Can we just use CMakeLists.txt which is the preferred way nowadays?
Thank you

aarch64 support

Are there any plans to add aarch64 support?
It won't cross-build but building on target I got it to configure but the compile fails with:

cc -DMLX_AARCH64 -DMLX_LINUX -DMLX_WITH_LIBDW -I/usr/include/elfutils/ -g -O2 -Wall -c -o breakpoint.o breakpoint.c
In file included from machines.h:4:0,
from breakpoint.c:15:
ptrace_utils.h: In function 'ptrace_get_regs':
ptrace_utils.h:25:9: error: 'PTRACE_GETREGS' undeclared (first use in this function)
ptrace(PTRACE_GETREGS, pid, 0, regs);
^
ptrace_utils.h:25:9: note: each undeclared identifier is reported only once for each function it appears in
ptrace_utils.h: In function 'ptrace_set_regs':
ptrace_utils.h:29:9: error: 'PTRACE_SETREGS' undeclared (first use in this function)
ptrace(PTRACE_SETREGS, pid, 0, regs);
^
breakpoint.c: In function 'do_breakpoint_init':
breakpoint.c:75:2: warning: implicit declaration of function 'set_breakpoint' [-Wimplicit-function-declaration]
set_breakpoint(pid, bp->entry_address, bp->entry_code);
^
: recipe for target 'breakpoint.o' failed
make: *** [breakpoint.o] Error 1

Memleax now available in FreeBSD ports collection

Hi,

I have added memleax to the FreeBSD ports collection, meaning it can now be installed on FreeBSD using:

pkg install memleax to install the package or cd /usr/ports/devel/memleax && make install clean to make and install from source.

Thanks for building a great tool!

Guy

Error: read maps of /usr/lib64/libaccountsservice.so.0.0.0

I was trying memleax to see if it might help find a memory leak I'm seeing and I'm getting the following error:

Error: read maps of /usr/lib64/libaccountsservice.so.0.0.0: 524288 290784

I've attached the content of /proc/196557/maps for the process.

pmap-196557.txt

Running multiple times I sometimes get errors processing other pmap entries:

$ ~/OSS/memleax/memleax 196557
Error: read maps of /home/eng/mneilly/.config/dconf/user: 524288 6308
$ ~/OSS/memleax/memleax 196557
Error: read maps of /usr/share/fonts/abattis-cantarell/Cantarell-Bold.otf: 65536 54824

Future supported architectures?

Hi!

Thank you for creating memleax. I've packaged it for Debian :-) https://packages.debian.org/sid/main/memleax

I'd also be happy to enable continuous integration using autopkgtest ( https://ci.debian.net/ ) if there are any self-tests that you'd like to run.

Finally, would you please let me know what architectures will not be supported in the future so that I can disable them? I think that it would be best to leave the ones for which support is planned enabled and let them fail (for now) on the Debian build servers, but I should explicitly disable support for the definitely unsupported ones.

The ones I'm not sure about these primary architectures: mips, mips64el, mipsel, powerpc, ppc64el, and s390x. There are more here https://buildd.debian.org/status/package.php?p=memleax&suite=unstable but they're secondary archs.

Sincerely,
Nicholas

P.S. if you're interested, here is the page for the requalification status for all primary archs for the next stable version. (Debian 10 aka "buster") https://release.debian.org/buster/arch_qualify.html

does memleax handle allocations from free list correctly?

Thanks for putting this out! I looks to be a very useful adjunct to other tools like valgrind, and covers a scenario that valgrind really doesn't handle very well.

I'm trying to use memleax to diagnose a problem with memory growing over time while a process is running. valgrind reports no leaks at shutdown, but top shows memory increasing steadily until the process is terminated.

But I'm having a problem, and I think it may be that malloc is returning the same block address that was previously freed -- since the address is the same memleax thinks that it exceeds the expire time, when in reality it has just been malloc'd and free'd over and over again.

Do you know if that's possible with memleax? If so, can you help point me to the code in memleax that timestamps the allocation? Perhaps that is not being updated with subsequent allocations after the first?

Thanks again for a terrific tool, and for any help you may be able to provide.

memleax crashes the monitored process too - using version 1.1.1-1

Hi,

I have been trying to use memleax. Am observing the problem of memleax crashes the targetted/monitored process also after few repetitions of starting and killing the memleax using CTRL+C
I have gone thru the discussions in this regard and suggestion to use version 1.1.1-1 but still seeing the issue.

Please let me know if you have any input in this regard. Following are my system details.

Linux OS10 4.9.110 #1 SMP Debian 4.9.110-3+deb9u4 x86_64

memleax does not report for Photon OS

Hi,

I have compiled memleax v1.1.1 sources for Photon OS, provided by vmware. I was able to compile the sources, and install it successfully. But it doesn't report any issues, for a sample code where i induced memory leak.

The tool outputs that it is monitoring the process, but no report generated.

Thanks

Does this support ARM platform

Hi WuBingzheng :

When I try to cross compile on ARM Platform, and the environment variables are as follows:

CC=arm-marvell-linux-gnueabi-gcc

I will get many compilation errors, does this support ARM platform ? thanks.

regards,
Kaloho

Docker support, custom locations for proc maps

One issue I noticed when trying to debug a leak in a docker container was that proc/pid/maps is an access denied unless you start the container in privileged mode.

I wonder if we can add an option to specify the location of the map, that way I can copy it from the host into the container when we need to debug

Memleax is killed after sometime while debugging process memory usage

Hi

I have compiled memleax for monitoring one of the process's memory usage/leak which is built using qt. I could see after some time memleax is killed with out of memory error.

Please help me to understand the memleax usage for debugging run-time memory usage of already running process.

Thanks & Regards,

BUG: miss breakpoint for multi-thread program

Steps:

  1. memleax set breakpoints at the entry of malloc and free at beginning;
  2. one thread runs in free;
  3. memleax catches it, set a breakpoint at the exit of free, and deletes the breakpoint at the entry of free temporarily to let the thread continue;
  4. if another thread runs in free now, memleax will miss it because the breakpoint is deleted!!! Then this memory block record will live for ever in memleax, and will be considered as a memory leak.

Similarly, if this happens at malloc, we will miss a memory block allocation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.