WuBingzheng / libleak

detect memory leak by LD_PRELOAD, without changing the target program
249 stars 52 forks source link

does not resolve line-numbers #14

Closed ghost closed 3 years ago

ghost commented 4 years ago

Hi,

When it finds a problem, it emits: ./constatus(_Z15send_index_htmlP13http_thread_tRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_P10instancetP6sourceS8+0x5f4) [0x555555916ca6]

That is without line-numbers. Can you maybe add that to libleak? Would be a great help :-)

WuBingzheng commented 4 years ago

Because the backtrace is showed by backtrace_symbols(2), which does not show the line number.

libleak used to show backtrace by libunwind, which can show line number. You may checkout that commit: https://github.com/WuBingzheng/libleak/commit/fec6426a388894f827715647abe30e382a660a91

ghost commented 4 years ago

Unfortunately that commit crashes at start.

WuBingzheng commented 4 years ago

Maybe you could try addr2line(1) to transfer addresses in libleak's log to line number.

WuBingzheng commented 4 years ago

I use libbacktrace to replace backtrace(3). So there are filename and number now.

ghost commented 4 years ago

Hi, Thanks! Unfortunately it immediately crashes:

==19850== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==19850== Bad permissions for mapped region at address 0x12055000 ==19850== at 0x483EA6E: strstr (vg_replace_strmem.c:1643) ==19850== by 0x4847674: lib_maps_build (libleak.c:172) ==19850== by 0x48478DE: init (libleak.c:340) ==19850== by 0x400F369: call_init.part.0 (dl-init.c:72) ==19850== by 0x400F468: call_init (dl-init.c:30) ==19850== by 0x400F468: _dl_init (dl-init.c:119) ==19850== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.30.so) ==19850== by 0x2: ??? ==19850== by 0x1FFEFFFED2: ??? ==19850== by 0x1FFEFFFEE2: ??? ==19850== by 0x1FFEFFFEE5: ???

WuBingzheng commented 4 years ago

Do you use LEAK_LIB_BLACKLIST? Would you like paste your command here? such as:

LD_PRELOAD=/home/wub/libleak/libleak.so LEAK_EXPIRE=2 LEAK_LIB_BLACKLIST=libmysqlclient.so LEAK_AFTER=1 ./a.out

Besides, would you like help to debug? Apply the following patch to print some debug info and show me the output.

Thanks Wu

diff --git a/libleak.c b/libleak.c
index 262c32e..d3e4983 100644
--- a/libleak.c
+++ b/libleak.c
@@ -169,6 +169,8 @@ static void lib_maps_build(void)
                lib->start = start;
                lib->end = end;
                if (conf_lib_blacklist != NULL) {
+                       printf("libleak debug: %s %s\n", conf_lib_blacklist, path);
+                       printf("libname: %s\n", lib->name);
                        lib->enabled = strstr(conf_lib_blacklist, lib->name) == NULL;
                } else {
                        lib->enabled = true;
ghost commented 4 years ago

Ok will help

Unfortunately it sometimes hangs in leak_current():

0 0x00007f7a55ed1c3b in __lll_lock_wait (futex=futex@entry=0x7f7a59cab000

, private=0) at lowlevellock.c:52 #1 0x00007f7a55eca893 in __GI___pthread_mutex_lock (mutex=mutex@entry=0x7f7a59cab000 ) at ../nptl/pthread_mutex_lock.c:80 #2 0x00007f7a59b9af8f in leak_current () at libleak.c:498 #3 0x00007f7a59b9b4a7 in leak_process_alloc (size=16, p=0x561276bd14f0) at libleak.c:544 #4 0x00007f7a59b9b4a7 in leak_process_alloc (p=0x561276bd14f0, size=16) at libleak.c:532 #5 0x00007f7a59b9b876 in malloc (size=16) at libleak.c:676 #6 0x00007f7a55d896eb in strdup () at /lib/x86_64-linux-gnu/libc.so.6 #7 0x00007f7a59b9a63c in lib_maps_build () at libleak.c:168 #8 0x00007f7a59b9a8ff in init () at libleak.c:342 #9 0x00007f7a59cbd36a in () at /lib64/ld-linux-x86-64.so.2 #10 0x00007f7a59cbd469 in () at /lib64/ld-linux-x86-64.so.2 #11 0x00007f7a59caf0ca in () at /lib64/ld-linux-x86-64.so.2 #12 0x0000000000000003 in () #13 0x00007fff9cdeffe6 in () #14 0x00007fff9cdefff6 in () #15 0x00007fff9cdefff9 in () #16 0x0000000000000000 in () So in this case my testprogram won't even start. On Mon, Jun 15, 2020 at 11:35 AM WuBingzheng wrote: > Do you use LEAK_LIB_BLACKLIST? Would you like paste your command here? > such as: > > LD_PRELOAD=/home/wub/libleak/libleak.so LEAK_EXPIRE=2 LEAK_LIB_BLACKLIST=libmysqlclient.so LEAK_AFTER=1 ./a.out > > Besides, would you like help to debug? Apply the following patch to print > some debug info and show me the output. > > Thanks > Wu > > diff --git a/libleak.c b/libleak.c > index 262c32e..d3e4983 100644 > --- a/libleak.c > +++ b/libleak.c > @@ -169,6 +169,8 @@ static void lib_maps_build(void) > lib->start = start; > lib->end = end; > if (conf_lib_blacklist != NULL) { > + printf("libleak debug: %s %s\n", conf_lib_blacklist, path); > + printf("libname: %s\n", lib->name); > lib->enabled = strstr(conf_lib_blacklist, lib->name) == NULL; > } else { > lib->enabled = true; > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub > , > or unsubscribe > > . > -- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl
WuBingzheng commented 4 years ago

more patch here, please try this. Thanks very much

diff --git a/libleak.c b/libleak.c
index 262c32e..0249d98 100644
--- a/libleak.c
+++ b/libleak.c
@@ -54,8 +54,8 @@ static pid_t (*leak_real_fork)(void); /* open new log file for new process */

 /* ### running flags */
-static bool leak_inited;
-static __thread bool leak_in_process;
+static bool leak_inited = false;
+static __thread bool leak_in_process = false;
 static FILE *leak_log_filp;
WuBingzheng commented 4 years ago

What's your OS and distribution?

ghost commented 4 years ago

Applied, no difference. To be sure I also initialized leak_log_filp with NULL.

This is debian 10 on a 64bit cpu.

On Mon, Jun 15, 2020 at 11:54 AM WuBingzheng notifications@github.com wrote:

more patch here, please try this. Thanks very much

diff --git a/libleak.c b/libleak.c index 262c32e..0249d98 100644 --- a/libleak.c +++ b/libleak.c @@ -54,8 +54,8 @@ static pid_t (leak_real_fork)(void); / open new log file for new process */

/ ### running flags / -static bool leak_inited; -static __thread bool leak_in_process; +static bool leak_inited = false; +static __thread bool leak_in_process = false; static FILE *leak_log_filp;

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/WuBingzheng/libleak/issues/14#issuecomment-644028316, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYRFODKVTVQYTSUBCTEHMTRWXVT3ANCNFSM4N2FTZJA .

-- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl

www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl

WuBingzheng commented 4 years ago

I will find a Debian to try it.

Please try a last patch (move the hooks down):

@@ -309,22 +311,6 @@ static void __attribute__((constructor))init(void)
                conf_start_ms = leak_now_ms() + atoi(ev) * 1000;
        }

-       /* hook symbols */
-       leak_real_malloc = dlsym(RTLD_NEXT, "malloc");
-       assert(leak_real_malloc != NULL);
-
-       leak_real_realloc = dlsym(RTLD_NEXT, "realloc");
-       assert(leak_real_realloc != NULL);
-
-       leak_real_calloc = dlsym(RTLD_NEXT, "calloc");
-       assert(leak_real_calloc != NULL);
-
-       leak_real_free = dlsym(RTLD_NEXT, "free");
-       assert(leak_real_free != NULL);
-
-       leak_real_fork = dlsym(RTLD_NEXT, "fork");
-       assert(leak_real_fork != NULL);
-
        /* init dict and memory pool */
        leak_callstack_dict = wuy_dict_new_func(leak_callstack_hash,
                        leak_callstack_equal,
@@ -354,6 +340,22 @@ static void __attribute__((constructor))init(void)
        fprintf(leak_log_filp, "# start detect. expire=%lds\n", conf_expire);
        fflush(leak_log_filp);

+       /* hook symbols */
+       leak_real_malloc = dlsym(RTLD_NEXT, "malloc");
+       assert(leak_real_malloc != NULL);
+
+       leak_real_realloc = dlsym(RTLD_NEXT, "realloc");
+       assert(leak_real_realloc != NULL);
+
+       leak_real_calloc = dlsym(RTLD_NEXT, "calloc");
+       assert(leak_real_calloc != NULL);
+
+       leak_real_free = dlsym(RTLD_NEXT, "free");
+       assert(leak_real_free != NULL);
+
+       leak_real_fork = dlsym(RTLD_NEXT, "fork");
+       assert(leak_real_fork != NULL);
+
        leak_inited = true;
 }
WuBingzheng commented 4 years ago

would you like paste you test-program here? Thanks

ghost commented 4 years ago

Hi,

I actually test with https://github.com/flok99/constatus

On Mon, Jun 15, 2020 at 12:10 PM WuBingzheng notifications@github.com wrote:

would you like paste you test-program here? Thanks

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/WuBingzheng/libleak/issues/14#issuecomment-644036570, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYRFOHI4YK77EDZELCQPCLRWXXSDANCNFSM4N2FTZJA .

-- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl

www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl

ghost commented 4 years ago

Hi,

This crashes with:

0 0x00007f5690e5c180 in tmp_buffer () at

/home/folkert/t/libleak/libleak.so

1 0x00007f5690de7868 in malloc (size=1024) at libleak.c:674

2 0x00007f568cfbbb9c in _IO_file_doallocate () at

/lib/x86_64-linux-gnu/libc.so.6

3 0x00007f568cfca250 in _IO_doallocbuf () at

/lib/x86_64-linux-gnu/libc.so.6

4 0x00007f568cfc9458 in _IO_file_overflow () at

/lib/x86_64-linux-gnu/libc.so.6

5 0x00007f568cfc856e in _IO_file_xsputn () at

/lib/x86_64-linux-gnu/libc.so.6

6 0x00007f568cfb1555 in () at /lib/x86_64-linux-gnu/libc.so.6

7 0x00007f568cf9e4eb in printf () at /lib/x86_64-linux-gnu/libc.so.6

8 0x00007f5690de667e in lib_maps_build () at libleak.c:172

9 0x00007f5690de6852 in init () at libleak.c:326

10 0x00007f5690f0936a in () at /lib64/ld-linux-x86-64.so.2

11 0x00007f5690f09469 in () at /lib64/ld-linux-x86-64.so.2

12 0x00007f5690efb0ca in () at /lib64/ld-linux-x86-64.so.2

13 0x0000000000000003 in ()

14 0x00007ffc788bcfe6 in ()

15 0x00007ffc788bcff6 in ()

16 0x00007ffc788bcff9 in ()

17 0x0000000000000000 in ()

On Mon, Jun 15, 2020 at 12:10 PM WuBingzheng notifications@github.com wrote:

I will find a Debian to try it.

Please try a last patch (move the hooks down):

@@ -309,22 +311,6 @@ static void attribute((constructor))init(void) conf_start_ms = leak_now_ms() + atoi(ev) * 1000; }

  • / hook symbols /

  • leak_real_malloc = dlsym(RTLD_NEXT, "malloc");

  • assert(leak_real_malloc != NULL);

  • leak_real_realloc = dlsym(RTLD_NEXT, "realloc");

  • assert(leak_real_realloc != NULL);

  • leak_real_calloc = dlsym(RTLD_NEXT, "calloc");

  • assert(leak_real_calloc != NULL);

  • leak_real_free = dlsym(RTLD_NEXT, "free");

  • assert(leak_real_free != NULL);

  • leak_real_fork = dlsym(RTLD_NEXT, "fork");

  • assert(leak_real_fork != NULL);

  • /* init dict and memory pool */
    leak_callstack_dict = wuy_dict_new_func(leak_callstack_hash,
                    leak_callstack_equal,

    @@ -354,6 +340,22 @@ static void attribute((constructor))init(void) fprintf(leak_log_filp, "# start detect. expire=%lds\n", conf_expire); fflush(leak_log_filp);

  • / hook symbols /

  • leak_real_malloc = dlsym(RTLD_NEXT, "malloc");

  • assert(leak_real_malloc != NULL);

  • leak_real_realloc = dlsym(RTLD_NEXT, "realloc");

  • assert(leak_real_realloc != NULL);

  • leak_real_calloc = dlsym(RTLD_NEXT, "calloc");

  • assert(leak_real_calloc != NULL);

  • leak_real_free = dlsym(RTLD_NEXT, "free");

  • assert(leak_real_free != NULL);

  • leak_real_fork = dlsym(RTLD_NEXT, "fork");

  • assert(leak_real_fork != NULL);

  • leak_inited = true;

    }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/WuBingzheng/libleak/issues/14#issuecomment-644036413, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYRFOBCYF4QVXGJQHNSEMLRWXXRBANCNFSM4N2FTZJA .

-- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl

www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl

WuBingzheng commented 4 years ago

Maybe you can keep the last patch only (move the hooks down), and remove the first patch (printf debug logs), and try again. Thanks for help.

WuBingzheng commented 4 years ago

Maybe your test-program is too complex. Would you like to try a simple one?

$ cat test1.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    char *a = malloc(1);
    printf("hello, \n");
    sleep(2);
    char *b = malloc(1);
    printf("world.\n");
    sleep(2);
    free(a);
    sleep(1);
    return 1;
}

$ cc test1.c -g
$ LD_PRELOAD=/home/wub/libleak/libleak.so LEAK_EXPIRE=1  ./a.out
$ cat /tmp/libleak.*
WuBingzheng commented 4 years ago

I think I have known the reason, and fixed it. Please try the newest commit.

ghost commented 4 years ago

Hi,

It now crashes somewhere else:

0 0x00007ffff762a940 in tmp_buffer () at /usr/local/libleak/libleak.so

1 0x00007ffff75bd6b7 in malloc (size=size@entry=14) at libleak.c:674

2 0x00007ffff234edba in __GI___strdup (s=0x7fffffffdeaa "libgcc_s.so.1")

at strdup.c:42

3 0x00007ffff75bc624 in lib_maps_build () at libleak.c:168

4 0x00007ffff75bc82d in init () at libleak.c:326

5 0x00007ffff7fe437a in call_init

(l=<optimized out>, argc=argc@entry=3, argv=argv@entry=0x7fffffffe3d8,

env=env@entry=0x7fffffffe3f8) at dl-init.c:72

6 0x00007ffff7fe4476 in call_init (env=0x7fffffffe3f8,

argv=0x7fffffffe3d8, argc=3, l=) at dl-init.c:30

7 0x00007ffff7fe4476 in _dl_init (main_map=0x7ffff7ffe190, argc=3,

argv=0x7fffffffe3d8, env=0x7fffffffe3f8) at dl-init.c:119

so there's progres!

On Tue, Jun 16, 2020 at 3:00 AM WuBingzheng notifications@github.com wrote:

I think I have known the reason, and fix it. Please try the newest commit.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/WuBingzheng/libleak/issues/14#issuecomment-644468070, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYRFOHTDS36UH5RDSD66LLRW273TANCNFSM4N2FTZJA .

-- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl

www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl

WuBingzheng commented 4 years ago

I install Debian 10.4, build your project constatus, test it with libleak, and it's OK.

wub@debian:~/constatus-master/build$ LD_PRELOAD=/home/wub/libleak/libleak.so ./constatus -c../constatus.cfg
2020-06-17 05:58:24.071737  INFO constatus  With libconfig 1.5.0
2020-06-17 05:58:24.072754  INFO constatus  Loading ../constatus.cfg...
2020-06-17 05:58:24.083192  INFO constatus   *** constatus v4.1 starting ***
2020-06-17 05:58:24.084694  INFO constatus  Generic resizer instantiated
2020-06-17 05:58:24.085459  INFO constatus  Configuring maintenance settings...
2020-06-17 05:58:24.091258  INFO constatus  Configuring default failure handling...
2020-06-17 05:58:24.091920  INFO constatus  Configuring the video-source 1-1...
Source-type "v4l" is not known
2020-06-17 05:58:24.093107 ERROR constatus  Source-type "v4l" is not known
wub@debian:~/constatus-master/build$ ls /tmp/libleak*
/tmp/libleak.9442  /tmp/libleak.9456  /tmp/libleak.9457

It's strange.

Do you mind to try the followings?

  1. I commit new code. Please pull and try it.

  2. Run a simple program with libleak in your environment.

ghost commented 4 years ago

Unfortunately it did not work. I dug a bit and found that you're using static arrays that may not be large enough depending on the application. For constatus, lib_maps must be > 100 entries. So I submitted a patch to you which makes it a dynamic array.

On Wed, Jun 17, 2020 at 12:10 PM WuBingzheng notifications@github.com wrote:

I install Debian 10.4, build your project constatus, test it with libleak, and it's OK.

wub@debian:~/constatus-master/build$ LD_PRELOAD=/home/wub/libleak/libleak.so ./constatus -c../constatus.cfg 2020-06-17 05:58:24.071737 INFO constatus With libconfig 1.5.0 2020-06-17 05:58:24.072754 INFO constatus Loading ../constatus.cfg... 2020-06-17 05:58:24.083192 INFO constatus constatus v4.1 starting 2020-06-17 05:58:24.084694 INFO constatus Generic resizer instantiated 2020-06-17 05:58:24.085459 INFO constatus Configuring maintenance settings... 2020-06-17 05:58:24.091258 INFO constatus Configuring default failure handling... 2020-06-17 05:58:24.091920 INFO constatus Configuring the video-source 1-1... Source-type "v4l" is not known 2020-06-17 05:58:24.093107 ERROR constatus Source-type "v4l" is not known wub@debian:~/constatus-master/build$ ls /tmp/libleak* /tmp/libleak.9442 /tmp/libleak.9456 /tmp/libleak.9457

It's strange.

Do you mind to try the followings?

1.

I commit new code. Please pull and try it. 2.

Run a simple program https://github.com/WuBingzheng/libleak/issues/14#issuecomment-644138889 with libleak in your environment.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/WuBingzheng/libleak/issues/14#issuecomment-645283518, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYRFOCBJBK7LUZC7Q6YBWDRXCJCHANCNFSM4N2FTZJA .

-- www.vanheusden.com www.slimwinnen.nl www.winnenmetbitcoin.nl

www.hackerspace-gouda.nl www.slimmetvalutahandelen.nl

WuBingzheng commented 4 years ago

Thanks very much for it. I add some comments at your patch. Would you like update it?