ASAN details - functions

0. Function:
Use after free (dangling pointer dereference)

Heap buffer overflow

Stack buffer overflow

Global buffer overflow

Use after return

Use after scope

Initialization order bugs

Memory leaks

Note: different versions may have different functions.
--------
Copyright notice: This is the original article of CSDN blogger "ACodeDog", which follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this notice for reprint.
Original link: https://blog.csdn.net/weixin_41644391/article/details/103450401

1,Use after free (dangling pointer dereference)

// RUN: clang -O -g -fsanitize=address %t && ./a.out
int main(int argc, char **argv) {
  int *array = new int[100];
  delete [] array;
  return array[argc];  // BOOM
}
=================================================================
==6254== ERROR: AddressSanitizer: heap-use-after-free on address 0x603e0001fc64 at pc 0x417f6a bp 0x7fff626b3250 sp 0x7fff626b3248
READ of size 4 at 0x603e0001fc64 thread T0
    #0 0x417f69 in main example_UseAfterFree.cc:5
    #1 0x7fae62b5076c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
    #2 0x417e54 (a.out+0x417e54)
0x603e0001fc64 is located 4 bytes inside of 400-byte region [0x603e0001fc60,0x603e0001fdf0)
freed by thread T0 here:
    #0 0x40d4d2 in operator delete[](void*) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:61
    #1 0x417f2e in main example_UseAfterFree.cc:4
previously allocated by thread T0 here:
    #0 0x40d312 in operator new[](unsigned long) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:46
    #1 0x417f1e in main example_UseAfterFree.cc:3
Shadow bytes around the buggy address:
  0x1c07c0003f30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x1c07c0003f80: fa fa fa fa fa fa fa fa fa fa fa fa[fd]fd fd fd
  0x1c07c0003f90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c07c0003fa0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c07c0003fb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x1c07c0003fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==6254== ABORTING

2,Heap buffer overflow

// RUN: clang -O -g -fsanitize=address %t && ./a.out
int main(int argc, char **argv) {
  int *array = new int[100];
  array[0] = 0;
  int res = array[argc + 100];  // BOOM
  delete [] array;
  return res;
}
=================================================================
==6226== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603e0001fdf4 at pc 0x417f8c bp 0x7fff64c0c010 sp 0x7fff64c0c008
READ of size 4 at 0x603e0001fdf4 thread T0
    #0 0x417f8b in main example_HeapOutOfBounds.cc:5
    #1 0x7fa97c09376c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
    #2 0x417e54 (a.out+0x417e54)
0x603e0001fdf4 is located 4 bytes to the right of 400-byte region [0x603e0001fc60,0x603e0001fdf0)
allocated by thread T0 here:
    #0 0x40d312 in operator new[](unsigned long) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:46
    #1 0x417f1c in main example_HeapOutOfBounds.cc:3
Shadow bytes around the buggy address:
  0x1c07c0003f60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003f80: fa fa fa fa fa fa fa fa fa fa fa fa 00 00 00 00
  0x1c07c0003f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c07c0003fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1c07c0003fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa
  0x1c07c0003fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003fe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0003ff0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c07c0004000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==6226== ABORTING

3,Stack buffer overflow

// RUN: clang -O -g -fsanitize=address %t && ./a.out
int main(int argc, char **argv) {
  int stack_array[100];
  stack_array[1] = 0;
  return stack_array[argc + 100];  // BOOM
}
=================================================================
==6240== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff8098b2b4 at pc 0x417fe1 bp 0x7fff8098b0f0 sp 0x7fff8098b0e8
READ of size 4 at 0x7fff8098b2b4 thread T0
    #0 0x417fe0 in main example_StackOutOfBounds.cc:5
    #1 0x7fa3667c976c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
    #2 0x417e54 (a.out+0x417e54)
Address 0x7fff8098b2b4 is located at offset 436 in frame <main> of T0's stack:
  This frame has 1 object(s):
    [32, 432) 'stack_array'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
  0x1ffff0131600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131620: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1ffff0131650: 00 00 00 00 00 00[f4]f4 f3 f3 f3 f3 00 00 00 00
  0x1ffff0131660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff0131690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ffff01316a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==6240== ABORTING

4,Global buffer overflow

// RUN: clang -O -g -fsanitize=address %t && ./a.out
int global_array[100] = {-1};
int main(int argc, char **argv) {
  return global_array[argc + 100];  // BOOM
}
=================================================================
==6211== ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000622314 at pc 0x417fee bp 0x7fff2e146300 sp 0x7fff2e1462f8
READ of size 4 at 0x000000622314 thread T0
    #0 0x417fed in main example_GlobalOutOfBounds.cc:4
    #1 0x7f1c10d2a76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
    #2 0x417ef4 (a.out+0x417ef4)
0x000000622314 is located 4 bytes to the right of global variable 'global_array (example_GlobalOutOfBounds.cc)' (0x622180) of size 400
Shadow bytes around the buggy address:
  0x1000000c4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1000000c4460: 00 00[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x1000000c4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c4490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c44a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000000c44b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==6211== ABORTING

5,Use after return

// RUN: clang -O -g -fsanitize=address %t && ./a.out
// By default, AddressSanitizer does not try to detect
// stack-use-after-return bugs.
// It may still find such bugs occasionally
// and report them as a hard-to-explain stack-buffer-overflow.

// You need to run the test with ASAN_OPTIONS=detect_stack_use_after_return=1

int *ptr;
__attribute__((noinline))
void FunctionThatEscapesLocalObject() {
  int local[100];
  ptr = &local[0];
}

int main(int argc, char **argv) {
  FunctionThatEscapesLocalObject();
  return ptr[argc];
}
=================================================================
==6268== ERROR: AddressSanitizer: stack-use-after-return on address 0x7fa19a8fc024 at pc 0x4180d5 bp 0x7fff73c3fc50 sp 0x7fff73c3fc48
READ of size 4 at 0x7fa19a8fc024 thread T0
    #0 0x4180d4 in main example_UseAfterReturn.cc:17
    #1 0x7fa19b11d76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
    #2 0x417f34 (a.out+0x417f34)
Address 0x7fa19a8fc024 is located at offset 36 in frame <_Z30FunctionThatEscapesLocalObjectv> of T0's stack:
  This frame has 1 object(s):
    [32, 432) 'local'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
  0x1ff43351f7b0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
  0x1ff43351f7c0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
  0x1ff43351f7d0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
  0x1ff43351f7e0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
  0x1ff43351f7f0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
=>0x1ff43351f800: f5 f5 f5 f5[f5]f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1ff43351f810: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1ff43351f820: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1ff43351f830: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 00 00 00 00
  0x1ff43351f840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1ff43351f850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==6268== ABORTING

6,Use after scope

// RUN: clang -O -g -fsanitize=address -fsanitize-address-use-after-scope \
//    use-after-scope.cpp -o /tmp/use-after-scope
// RUN: /tmp/use-after-scope

// Check can be disabled in run-time:
// RUN: ASAN_OPTIONS=detect_stack_use_after_scope=0 /tmp/use-after-scope

volatile int *p = 0;

int main() {
  {
    int x = 0;
    p = &x;
  }
  *p = 5;
  return 0;
}
=================================================================
==58237==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc4d830880 at pc 0x0000005097ed bp 0x7ffc4d830850 sp 0x7ffc4d830848
WRITE of size 4 at 0x7ffc4d830880 thread T0
    #0 0x5097ec  (/tmp/use-after-scope+0x5097ec)
    #1 0x7ff85fa6bf44  (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #2 0x41a005  (/tmp/use-after-scope+0x41a005)

Address 0x7ffc4d830880 is located in stack of thread T0 at offset 32 in frame
    #0 0x5096ef  (/tmp/use-after-scope+0x5096ef)

  This frame has 1 object(s):
    [32, 36) 'x' <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope (/tmp/use-after-scope+0x5097ec) 
Shadow bytes around the buggy address:
  0x100009afe0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe100: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x100009afe110:[f8]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100009afe160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==58237==ABORTING

7,Initialization order bugs

Static initialization order failure is a common problem related to the order of constructing global objects in C + + programs. The running order of constructors for global objects in different source files was not specified. Parashift C++ FAQ Sections 10.14-10.18 It explains well what the problem is and what can be done to correct it. This is a short example:

$ cat tmp/init-order/example/a.cc
#include <stdio.h>
extern int extern_global;
int __attribute__((noinline)) read_extern_global() {
  return extern_global;
}
int x = read_extern_global() + 1;
int main() {
  printf("%d\n", x);
  return 0;
}

$ cat tmp/init-order/example/b.cc
int foo() { return 42; }
int extern_global = foo();

The value ifx here depends on the value extern_global, depending on the order in which the initialization program of the translation unit runs, it may or may not be initialized to "42":

$ clang++ tmp/init-order/example/a.cc tmp/init-order/example/b.cc && ./a.out 
1
$ clang++ tmp/init-order/example/b.cc tmp/init-order/example/a.cc && ./a.out 
43

These errors are difficult to detect and may be ignored until some irrelevant changes in the code (or compiler or link strategy) change the code behavior and usually destroy it in unexpected ways.

In AddressSanitizer Initialize sequence checker

AddressSanitizer The check is inserted into the compiler to detect initialization order problems. By default, they are closed and you must pass them Runtime flag To enable them. see also Example usage.

Loose initialization sequence check

This mode reports an error if the initializer of a global variable accesses a dynamically initialized global from another uninitialized translation unit. Using check_initialization_order=true to activate it:

$ clang++ -fsanitize=address -g tmp/init-order/example/a.cc tmp/init-order/example/b.cc
$ ASAN_OPTIONS=check_initialization_order=true ./a.out
=================================================================
==26772==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x000001068820 at pc 0x427e74 bp 0x7ffff8295010 sp 0x7ffff8295008
READ of size 4 at 0x000001068820 thread T0
    #0 0x427e73 in read_extern_global() tmp/init-order/example/a.cc:4
    #1 0x42806c in __cxx_global_var_init tmp/init-order/example/a.cc:7
    #2 0x4280d5 in global constructors keyed to a tmp/init-order/example/a.cc:10
    #3 0x42823c in __libc_csu_init (a.out+0x42823c)
    #4 0x7f9afdbdb6ff (/lib/x86_64-linux-gnu/libc.so.6+0x216ff)
    #5 0x427d64 (a.out+0x427d64)
0x000001068820 is located 0 bytes inside of global variable 'extern_global' from 'tmp/init-order/example/b.cc' (0x1068820) of size 4
SUMMARY: AddressSanitizer: initialization-order-fiasco tmp/init-order/example/a.cc:4 read_extern_global()
<...>

In a sense, this model reports problems. If the initialization sequence changes, an error may not be reported:

$ clang++ -fsanitize=address -g tmp/init-order/example/b.cc tmp/init-order/example/a.cc
$ ASAN_OPTIONS=check_initialization_order=true ./a.out
43

Strict initialization sequence check

This mode reports an error if the initializer of a global variable accesses any dynamically initialized global variables from another translation unit. Use the additional variable strict_init_order=true to activate it:

$ clang++ -fsanitize=address -g tmp/init-order/example/b.cc tmp/init-order/example/a.cc
$ ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true ./a.out
=================================================================
==27853==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x0000010687e0 at pc 0x427f74 bp 0x7fff3d076ba0 sp 0x7fff3d076b98
READ of size 4 at 0x0000010687e0 thread T0
    #0 0x427f73 in read_extern_global() tmp/init-order/example/a.cc:4
<...>

In this way, you may also find potential initialization order problems.

False alarm

  • Strict initialization order checking may report false positives when it is expected to access initialized global variables from another translation unit, or when a specific construction order is enforced, for example, by using a shared library.
  • A loose initialization order check may report false positives for dynamically initialized global variables that can still be safely accessed before initialization (for example, if their constructors do nothing).

blacklist

You can suppress the false positives of the init order checker on some global variables by using the - fsanitize blacklist = path / to / blacklist.txt option. Relevant blacklist entries are:

# Disable init-order checking for a single variable:
global:bad_variable=init
# Disable checking for all variables of a given type:
type:Namespace::ClassName=init
# Disable checking for all variables in given files:
src:path/to/bad/files/*=init

performance

Init order slows down program startup. Its complexity is O(NM), where N is the total number of dynamically initialized global variables M in binary and the total number of translation units.

8,Memory leaks

introduce

LeakSanitizer is a memory leak detector that is integrated into In AddressSanitizer . The tool is in x86_ 64 supported on Linux and OS X.

LeakSanitizer in x86_ 64 is enabled by default in the ASan version of Linux, and ASan can be used_ OPTIONS=detect_ Leaks = 1 in x86_ Enabled on 64 OS X. The LSan is dormant until the end of the process, when there is an additional leak detection phase. In performance critical scenarios, LSan can also be used without ASan detection.

See also: Design documents´╝îComparison with tcmalloc's heap leak checker

Using LeakSanitizer

To use LSan, simply use AddressSanitizer Build your application:

$ cat memory-leak.c 
#include <stdlib.h>

void *p;

int main() {
  p = malloc(7);
  p = 0; // The memory is leaked here.
  return 0;
}
$ clang -fsanitize=address -g memory-leak.c
$ ./a.out 

=================================================================
==7829==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 7 byte(s) in 1 object(s) allocated from:
    #0 0x42c0c5 in __interceptor_malloc /usr/home/hacker/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
    #1 0x43ef81 in main /usr/home/hacker/memory-leak.c:6
    #2 0x7fef044b876c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

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

If you want to run the Yashan instrument program without leakage detection, you can use detect_leaks=0 in ASAN_OPTIONS environment variable.

standalone mode

If you only need leak detection and are not willing to bear the three slowdown, you can create - fsanitize=leak instead of - fsanitize=address. This links your program to a runtime library that contains only the basic necessities needed for the work of LeakSanitizer. No compile time detection will be applied.

Note that independent mode is less effective than running LSan on top of ASan.

flag

You can use lsan_ The options environment variable fine tunes the behavior of the LeakSanitizer.

flagdefaultdescribe
Exit code 23 If non-zero, LSan will call_ exit(exitcode) detects leaks. This may be different from the exit code used to signal an ASan error.
Maximum leakage 0 If non-zero, only so many top-level leaks are reported.
suppress (no) File path containing suppression rules (see below)
Print suppression 1 If 1, the statistics of match suppression are printed.
Report object 0 If 1, LSan will report the address of the individual leak object.
use_unaligned 0 If 0, LSan will only consider the correctly aligned 8-byte pattern when looking for pointers. Set to 1 to include misaligned patterns. This refers to the pointer itself, not to the memory.

Leak detection is also subject to certain restrictions ASan logo influence. If you are unhappy with the stack trace you see, check fast_unwind_on_malloc´╝îmalloc_context_size and strip_path_prefix. Those signs ASAN_OPTIONS enters as usual. However, if you use build - fsanitize=leak, put them in the LSAN_OPTIONS (and used for LSAN_SYMBOLIZER_PATH to pass symbol paths).

inhibition

You can instruct LeakSanitizer to ignore some leaks by passing in a suppression file. Each line of the file must contain a suppression rule, and the format of each rule is leak: < pattern >   This pattern will substring match the leaked symbol stack trace. If the function name, source file name, or binary file name match, the leak report is suppressed.

$ cat suppr.txt 
# This is a known leak.
leak:FooBar
$ cat lsan-suppressed.cc 
#include <stdlib.h>

void FooBar() {
  malloc(7);
}

void Baz() {
  malloc(5);
}

int main() {
  FooBar();
  Baz();
  return 0;
}
$ clang++ lsan-suppressed.cc -fsanitize=address
$ ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=suppr.txt ./a.out

=================================================================
==26475==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 5 byte(s) in 1 object(s) allocated from:
    #0 0x44f2de in malloc /usr/home/hacker/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
    #1 0x464e86 in Baz() (/usr/home/hacker/a.out+0x464e86)
    #2 0x464fb4 in main (/usr/home/hacker/a.out+0x464fb4)
    #3 0x7f7e760b476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

-----------------------------------------------------
Suppressions used:[design document](AddressSanitizerLeakSanitizerDesignDocument)
  count      bytes template
      1          7 FooBar
-----------------------------------------------------

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

The special symbols ^ and $match the beginning and end of the string.

Posted on Wed, 01 Dec 2021 02:22:21 -0500 by robgudgeon