Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress leak checking on exit #719

Open
jmithmstr opened this issue Sep 5, 2016 · 15 comments
Open

Suppress leak checking on exit #719

jmithmstr opened this issue Sep 5, 2016 · 15 comments

Comments

@jmithmstr
Copy link

I am working on a software where the developers think that it is OK to not free memory still reacheable on exit. I am only interested in leaks while the program is running.
Is there a way to suppress leak checking on exit?

@chefmax
Copy link

chefmax commented Sep 5, 2016

Do you mean suppressing all leaks? If so, use LSAN_OPTIONS=detect_leaks=0. If you want to suppress only some particular leaks, use LSAN_OPTIONS=suppressions= interface.

@jmithmstr
Copy link
Author

No, I do not want to suppress all leaks. I just want to suppress leaks of memory still reachable on exit. But, I still want to see leaks of memory that are not reachable anymore.

@chefmax
Copy link

chefmax commented Sep 5, 2016

Hm, LSan shouldn't report reachable memory blocks, it reports only not reachable ones.

@jmithmstr
Copy link
Author

LSan reports reachable memory blocks on exit.
See:
#include <stdlib.h>
int
main (int argc, char *argv[])
{
void *a;
a = malloc(1);
return 0;
}

==17315==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x7f4ecb8ebe38 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1e38)
#1 0x40071e in main memleak.c:7
#2 0x7f4ecb4a96ff in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x206ff)

SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).

@yugr
Copy link

yugr commented Sep 5, 2016

Given that you don't use a, compiler might have removed it from main's stack...

@jmithmstr
Copy link
Author

The program:
#include <stdlib.h>
int
main (int argc, char *argv[])
{
char *a;
a = malloc(1);
*a = 'a';
return 0;
}

Compiled using:
gcc -g -fsanitize=address -fno-omit-frame-pointer -Wall -o memleak memleak.c

still shows reachable leaks on exit.

I have seen that if I call exit(0) reachable leaks are not reported anymore.
But, how may I do the same if the program does not call exit() ?

@chefmax
Copy link

chefmax commented Sep 5, 2016

It seems that a is out of scope when LSan performs analysis. Could you:

  1. add printf("%p\n", &a);
  2. run your testcase with LSAN_OPTIONS=log_pointers=1
    ?

@jmithmstr
Copy link
Author

This is the new output:
0x7ffec5325f10
==1562==Scanning GLOBAL range 0x000000601000-0x000000601300.
==1562==Scanning GLOBAL range 0x7fa07e169718-0x7fa07e16ed60.
==1562==Scanning GLOBAL range 0x7fa07e36efe8-0x7fa07ede0d90.
==1562==Scanning GLOBAL range 0x7fa07de3c7c8-0x7fa07de459a0.
==1562==0x7fa07de41628: found 0x61900000b480 pointing into chunk 0x61900000b480-0x61900000b880 of size 1024.
==1562==Scanning GLOBAL range 0x7fa07daa3d60-0x7fa07daa40f0.
==1562==Scanning GLOBAL range 0x7fa07d89fd58-0x7fa07d8a0bc0.
==1562==Scanning GLOBAL range 0x7fa07d693b78-0x7fa07d698428.
==1562==Scanning GLOBAL range 0x7fa07d46c338-0x7fa07d47b260.
==1562==0x7fa07d477be8: found 0x631000000800 pointing into chunk 0x631000000800-0x631000012400 of size 72704.
==1562==Scanning GLOBAL range 0x7fa07d0f9d70-0x7fa07d0fa0e8.
==1562==Scanning GLOBAL range 0x7fa07cdf52d0-0x7fa07cdf5950.
==1562==Scanning GLOBAL range 0x7fa07f004bc0-0x7fa07f006168.
==1562==Scanning REGISTERS range 0x7fa07efaf000-0x7fa07efaf0d8.
==1562==Scanning STACK range 0x7ffec5325bc8-0x7ffec5328000.
==1562==Scanning TLS range 0x7fa07efc1000-0x7fa07efc2080.
==1562==Scanning HEAP range 0x631000000800-0x631000012400.
==1562==Scanning HEAP range 0x61900000b480-0x61900000b880.
==1562==Processing platform-specific allocations.
==1562==Scanning leaked chunks.
==1562==Scanning HEAP range 0x60200000eff0-0x60200000eff1.

==1554==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x7fa07df07e38 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1e38)
#1 0x4009a6 in main memleak.c:8
#2 0x7fa07dac56ff in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x206ff)

SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).

for:
#include <stdlib.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
char *a;
a = malloc(1);
*a = 'a';
printf("%p\n", &a);
return 0;
}

@yugr
Copy link

yugr commented Sep 5, 2016

I think when you call exit(), main's stack frame is still active so LSan can find reference to allocated block there whereas in alternative case the frame is already destroyed and so not considered.

@dvyukov
Copy link
Contributor

dvyukov commented Sep 5, 2016

On Mon, Sep 5, 2016 at 12:57 PM, jmithmstr [email protected] wrote:

This is the new output:
0x7ffec5325f10
==1562==Scanning GLOBAL range 0x000000601000-0x000000601300.
==1562==Scanning GLOBAL range 0x7fa07e169718-0x7fa07e16ed60.
==1562==Scanning GLOBAL range 0x7fa07e36efe8-0x7fa07ede0d90.
==1562==Scanning GLOBAL range 0x7fa07de3c7c8-0x7fa07de459a0.
==1562==0x7fa07de41628: found 0x61900000b480 pointing into chunk
0x61900000b480-0x61900000b880 of size 1024.
==1562==Scanning GLOBAL range 0x7fa07daa3d60-0x7fa07daa40f0.
==1562==Scanning GLOBAL range 0x7fa07d89fd58-0x7fa07d8a0bc0.
==1562==Scanning GLOBAL range 0x7fa07d693b78-0x7fa07d698428.
==1562==Scanning GLOBAL range 0x7fa07d46c338-0x7fa07d47b260.
==1562==0x7fa07d477be8: found 0x631000000800 pointing into chunk
0x631000000800-0x631000012400 of size 72704.
==1562==Scanning GLOBAL range 0x7fa07d0f9d70-0x7fa07d0fa0e8.
==1562==Scanning GLOBAL range 0x7fa07cdf52d0-0x7fa07cdf5950.
==1562==Scanning GLOBAL range 0x7fa07f004bc0-0x7fa07f006168.
==1562==Scanning REGISTERS range 0x7fa07efaf000-0x7fa07efaf0d8.
==1562==Scanning STACK range 0x7ffec5325bc8-0x7ffec5328000.
==1562==Scanning TLS range 0x7fa07efc1000-0x7fa07efc2080.
==1562==Scanning HEAP range 0x631000000800-0x631000012400.
==1562==Scanning HEAP range 0x61900000b480-0x61900000b880.
==1562==Processing platform-specific allocations.
==1562==Scanning leaked chunks.
==1562==Scanning HEAP range 0x60200000eff0-0x60200000eff1.

==1554==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x7fa07df07e38 in malloc (/usr/lib/x86_64-linux-gnu/
libasan.so.3+0xc1e38)
#1 #1 0x4009a6 in main
memleak.c:8
#2 #2 0x7fa07dac56ff in
__libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x206ff)

SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).

for:
#include
#include
int
main (int argc, char *argv[])
{
char *a;
a = malloc(1);
*a = 'a';
printf("%p\n", &a);
return 0;
}

Try to manually execute __lsan_do_leak_check() at the point where you are
still interested in leaks and then __lsan_disable() to disable at exit
checking.

@jmithmstr
Copy link
Author

OK, the code works as expected, and there is no need for any enhancement.

Maybe the documentation could be improved to document this use case.

@morehouse
Copy link
Contributor

WAI

@vitalybuka vitalybuka reopened this Sep 15, 2020
@vitalybuka
Copy link
Contributor

Maybe we still should consider to always suppress leak checks for exit()?
Different levels of optimization may hide some stack pointers from the lsan and make reports inconsistent.

My concern is that maybe some users already expect lsan even for exit() and if we change that we will brake them.
If we don't want to change this behavior then we need to describe this in documentation.
@kcc WDYT?

@kcc
Copy link
Contributor

kcc commented Sep 16, 2020

yea, that sounds like breaking an existing useful functionality...

Different levels of optimization may hide some stack pointers from the lsan and make reports inconsistent.

Do we understand how it happens?
Don't we look in the registers for roots?

@vitalybuka
Copy link
Contributor

Do we understand how it happens?
No. I can't reproduce myself. It's a very specific binary.

Don't we look in the registers for roots?
We do. But I recently discovered a bug and we may look not enough https://reviews.llvm.org/D87754

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants