Reputation: 1270
I am use -fsanitize=leak
and -fsanitize=address
in my project. I thought that leak finds memory leaks(doesn't delete memory) and address finds wring memory access. But address also says about not-deleted memory. So, for what purposes -fsanitize=leak
are needed?
Upvotes: 9
Views: 4790
Reputation: 33
LeakSanitizer is a memory leak detector which is integrated into AddressSanitizer.
If you just need leak detection, and don't want to bear the ASan slowdown, you can build with -fsanitize=leak instead of -fsanitize=address. This will link your program against a runtime library containing just the bare necessities required for LeakSanitizer to work. No compile-time instrumentation will be applied.
ASAN_OPTIONS=detect_leaks=1 clang/gcc -fsanitize=address -g
https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer
or same from llvm:
https://clang.llvm.org/docs/LeakSanitizer.html
But: running with --sanitize=leak seams to make different options avialable via LSAN_OPTION which are not avialable or ignored if you run --sanitze=address. Thats what i found by runnit help=1 to one of the enviroment variables.
Enable both with --sanitize=leak,address (--sanitize=address,leak) have no effekt. Leak options itselfe are still ignored by LSAN_OPTIONS=help=1 but prints the ASAN_OPTIONS --> it seams truly to be because address incudes leak (mostly or full).
Upvotes: 2
Reputation: 423
The address sanitizer does a bunch of extra stuff like checking if you are writing to memory that is out of bounds. The leak sanitizer just checks if you forget to free memory.
You can read about these on the gcc program instrumentation options page.
-fsanitize=address
Enable AddressSanitizer, a fast memory error detector. Memory access instructions are instrumented to detect out-of-bounds and use-after-free bugs. The option enables -fsanitize-address-use-after-scope
. See https://github.com/google/sanitizers/wiki/AddressSanitizer for more details. The run-time behavior can be influenced using the ASAN_OPTIONS
environment variable. When set to help=1
, the available options are shown at startup of the instrumented program. See https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags for a list of supported options. The option cannot be combined with -fsanitize=thread
.
-fsanitize=leak
Enable LeakSanitizer, a memory leak detector. This option only matters for linking of executables and the executable is linked against a library that overrides malloc and other allocator functions. See https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer for more details. The run-time behavior can be influenced using the LSAN_OPTIONS
environment variable. The option cannot be combined with -fsanitize=thread
.
-fsanitize-address-use-after-scope
Enable sanitization of local variables to detect use-after-scope bugs. The option sets -fstack-reuse
to none
.
-fstack-reuse=reuse-level
Documentation can be found on the code gen options page.
This option controls stack space reuse for user declared local/auto variables and compiler generated temporaries. reuse_level can be ‘all’, ‘named_vars’, or ‘none’. ‘all’ enables stack reuse for all local variables and temporaries, ‘named_vars’ enables the reuse only for user defined local variables with names, and ‘none’ disables stack reuse completely. The default value is ‘all’. The option is needed when the program extends the lifetime of a scoped local variable or a compiler generated temporary beyond the end point defined by the language. When a lifetime of a variable ends, and if the variable lives in memory, the optimizing compiler has the freedom to reuse its stack space with other temporaries or scoped local variables whose live range does not overlap with it. Legacy code extending local lifetime is likely to break with the stack reuse optimization.
For example,
int *p;
{
int local1;
p = &local1;
local1 = 10;
....
}
{
int local2;
local2 = 20;
....
}
if (*p == 10) // out of scope use of local1
{
}
Another example:
struct A {
A(int k) : i(k), j(k) { }
int i;
int j;
};
A *ap;
void foo(const A& ar) {
ap = &ar;
}
void bar() {
foo(A(10)); // temp object's lifetime ends when foo returns
{
A a(20);
....
}
ap->i += 10; // ap references out of scope temp whose space
// is reused with a. What is the value of ap->i?
}
The lifetime of a compiler generated temporary is well defined by the C++ standard. When a lifetime of a temporary ends, and if the temporary lives in memory, the optimizing compiler has the freedom to reuse its stack space with other temporaries or scoped local variables whose live range does not overlap with it. However some of the legacy code relies on the behavior of older compilers in which temporaries’ stack space is not reused, the aggressive stack reuse can lead to runtime errors. This option is used to control the temporary stack reuse optimization.
Upvotes: 12
Reputation: 474236
In order to find memory leaks, the tool needs to look at all places where you allocate memory, mark them, track when they're deleted, and see if any are left undeleted at the end of the program.
In order to find memory writing access violations, the tool needs to (among other things) look at all the places where you allocate memory, mark them, and track when they're deleted. This is necessary because it's going to make the allocations bigger, so that it can put guards around them to detect when you're making wild writes.
So basically 90% of the information needed to track memory leaks is available to address sanitizer. So it may as well track those too.
The reason you don't use address sanitizer just to find memory leaks is that it does a whole lot of other stuff.
Upvotes: 3