当前位置:网站首页>Initial experience of addresssanitizer Technology
Initial experience of addresssanitizer Technology
2022-07-07 06:52:00 【YAN_ RONG_ TECHNOLOGY】
brief introduction
AddressSanitizer yes Google Developed a tool for detecting memory access errors , For resolution use-after-free And memory leaks . It's built into GCC edition >= 4.8 in , Apply to C and C++ Code .AddressSanitizer Trace memory allocation can be detected when using runtime , This means that you must use AddressSanitizer Build code to take advantage of its functions .
Because memory leakage will increase the total memory used by the program , So when memory is no longer needed , It is important to free memory correctly . Maybe for applets , Losing a few bytes doesn't seem like a big deal , But for long-running programs that use a lot of memory , Avoiding memory leaks is becoming increasingly important . If the program no longer needs it , Unable to free used memory , It is likely to run out of memory , This causes the application to terminate prematurely .AddressSanitizer Appearance , Can help detect these memory leaks .
Besides ,AddressSanitizer It can detect use-after-free error . When a program attempts to read or write to memory that has been freed , Post release use errors will occur . This is undefined behavior , May cause data corruption 、 The result is not correct , Even the program crashed .
If an error is detected , The program will stderr Print error messages , And exit with a non-zero exit code , If you use AddressSanitizer, Then it exits at the first detected error .
Be careful
ASan Use your own memory allocator (malloc, free etc. )
ASan Use a lot of virtual address space (x86_64 Linux Up for 20T)
Use
-fsanitize=address Flags are used to tell the compiler , Will add AddressSanitizer, It is very helpful to compile code with debugging symbols . If there are debug symbols , need AddressSanitizer Print line number , Then please add -g sign . Besides , If you find that the stack trace looks incorrect , Use -fno-omit-frame-pointer You can display more detailed call stack information , Merge into one command to generate executable :
gcc main.cpp -o main -g -fsanitize=addressThis code is Bash
perhaps , Separate compilation and linking phases :
gcc -c main.cpp -fsanitize=address -g -fno-omit-frame-pointer
gcc main.o -o main -fsanitize=addressThis code is Bash
Please note that , Both compilation and linking steps need -fsanitize=address sign . If building a system is more complex , Put these signs on CXXFLAGS and LDFLAGS In the environment variables .
performance
AddressSanitizer Compared with tools for similar analysis ( Such as valgrind) Much faster . For better performance, you can use -O1 Or higher optimization .
however , If you feel AddressSanitizer Too slow for some code , You can disable it by using the compiler flag , For specific functions . It helps to use in the colder part of the code AddressSanitizer, At the same time, manually audit the hot path .
The compiler instruction to skip the analysis function is __attribute__((no_sanitize_address).
Wrong type
1. Use after free
Memory is also used after it is released .
int main(int argc, char **argv) {
int *array = new int[100];
delete [] array;
return array[argc]; // BOOM
} This code is C
=================================================================
==3262==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000044 at pc 0x55c005566d89 bp 0x7fffc64dc040 sp 0x7fffc64dc030
READ of size 4 at 0x614000000044 thread T0
#0 0x55c005566d88 in main /root/study/cmakeutils/src/main.cpp:6
#1 0x7fdb76b17082 in __libc_start_main ../csu/libc-start.c:308
#2 0x55c005566c4d in _start (/root/study/cmakeutils/build/main+0xdc4d)
0x614000000044 is located 4 bytes inside of 400-byte region [0x614000000040,0x6140000001d0)
freed by thread T0 here:
#0 0x7fdb77396b97 in operator delete[](void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:163
#1 0x55c005566d3c in main /root/study/cmakeutils/src/main.cpp:5
#2 0x7fdb76b17082 in __libc_start_main ../csu/libc-start.c:308
previously allocated by thread T0 here:
#0 0x7fdb77396097 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:102
#1 0x55c005566d25 in main /root/study/cmakeutils/src/main.cpp:4
#2 0x7fdb76b17082 in __libc_start_main ../csu/libc-start.c:308
...This code is Bash
The first 4 Line shows READ( Memory read ) The location of ,return array[argc];
The first 10 Line shows freed( Memory free ) The location of ,delete [] array;
The first 16 Line shows allocate( Memory application ) The location of ,int *array = new int[100].
2. Heap buffer overflow
Heap space requested , The array subscript is out of the application range .
int main(int argc, char **argv) {
int *array = new int[100];
array[0] = 0;
int res = array[argc + 100]; // BOOM
delete [] array;
return res;
}This code is C++
=================================================================
==3407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d4 at pc 0x55753d9b4dbb bp 0x7ffe7d1e77e0 sp 0x7ffe7d1e77d0
READ of size 4 at 0x6140000001d4 thread T0
#0 0x55753d9b4dba in main /root/study/cmakeutils/src/main.cpp:6
#1 0x7f9f5683b082 in __libc_start_main ../csu/libc-start.c:308
#2 0x55753d9b4c4d in _start (/root/study/cmakeutils/build/main+0xdc4d)
0x6140000001d4 is located 4 bytes to the right of 400-byte region [0x614000000040,0x6140000001d0)
allocated by thread T0 here:
#0 0x7f9f570ba097 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:102
#1 0x55753d9b4d25 in main /root/study/cmakeutils/src/main.cpp:4
#2 0x7f9f5683b082 in __libc_start_main ../csu/libc-start.c:308
...This code is Bash
The first 4 Line shows READ The location of ,int res = array[argc + 100];
The first 11 Line shows allocate The location of ,int *array = new int[100];
Because here argc + 100 >= 100, array Subscript to be 0-99, So there's a mistake .
3. Stack buffer overflow
local variable , Array subscript is out of range .
int main(int argc, char **argv) {
int stack_array[100];
stack_array[1] = 0;
return stack_array[argc + 100]; // BOOM
}This code is C++
=================================================================
==3529==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff4c128d44 at pc 0x55ccafbf0e13 bp 0x7fff4c128b60 sp 0x7fff4c128b50
READ of size 4 at 0x7fff4c128d44 thread T0
#0 0x55ccafbf0e12 in main /root/study/cmakeutils/src/main.cpp:6
#1 0x7f624dc97082 in __libc_start_main ../csu/libc-start.c:308
#2 0x55ccafbf0c0d in _start (/root/study/cmakeutils/build/main+0xdc0d)
Address 0x7fff4c128d44 is located in stack of thread T0 at offset 452 in frame
#0 0x55ccafbf0cd8 in main /root/study/cmakeutils/src/main.cpp:3
This frame has 1 object(s):
[48, 448) 'stack_array' (line 4) <== Memory access at offset 452 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
...This code is Bash
The first 4 Line shows READ The location of ,return stack_array[argc + 100];
The first 12 Line shows the position of the variable ,int stack_array[100].
4. Global buffer overflow
Global variables , Array subscript is out of range .
int global_array[100] = {-1};
int main(int argc, char **argv) {
return global_array[argc + 100]; // BOOM
}This code is C++
=================================================================
==3653==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55b61f0391b4 at pc 0x55b61efd7d2b bp 0x7fff8bc1cbd0 sp 0x7fff8bc1cbc0
READ of size 4 at 0x55b61f0391b4 thread T0
#0 0x55b61efd7d2a in main /root/study/cmakeutils/src/main.cpp:5
#1 0x7f0637717082 in __libc_start_main ../csu/libc-start.c:308
#2 0x55b61efd7c0d in _start (/root/study/cmakeutils/build/main+0xdc0d)
0x55b61f0391b4 is located 4 bytes to the right of global variable 'global_array' defined in '/root/study/cmakeutils/src/main.cpp:3:5' (0x55b61f039020) of size 400
...This code is Bash
The first 4 Line shows READ The location of ,return global_array[argc + 100];
The first 8 The row shows the location of the global variable ,int global_array[100] = {-1}.
5. Use after return
The pointer points to a local variable of a function , The local variable fails after the function returns , But this pointer is used .
// This item is not detected by default , Can be set up ASAN_OPTIONS=detect_stack_use_after_return=1 Turn on detection
int* ptr;
__attribute__((noinline)) void FunctionThatEscapesLocalObject() {
int local[100];
ptr = &local[0];
}
int main(int argc, char** argv) {
FunctionThatEscapesLocalObject();
return ptr[argc];
}This code is C++
=================================================================
==3811==ERROR: AddressSanitizer: stack-use-after-return on address 0x7fd77133e234 at pc 0x555fb157be71 bp 0x7fffdb165710 sp 0x7fffdb165700
READ of size 4 at 0x7fd77133e234 thread T0
#0 0x555fb157be70 in main /root/study/cmakeutils/src/main.cpp:11
#1 0x7fd7746db082 in __libc_start_main ../csu/libc-start.c:308
#2 0x555fb157bc0d in _start (/root/study/cmakeutils/build/main+0xdc0d)
Address 0x7fd77133e234 is located in stack of thread T0 at offset 52 in frame
#0 0x555fb157bcd8 in FunctionThatEscapesLocalObject() /root/study/cmakeutils/src/main.cpp:4
This frame has 1 object(s):
[48, 448) 'local' (line 5) <== Memory access at offset 52 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
...This code is Bash
The first 4 Row display READ Location ,return ptr[argc];
The first 12 The line shows the position of the variable ,int local[100];
here ptr Points to the address of a local variable ptr = &local[0], And then in FunctionThatEscapesLocalObject When the function returns , Visit the address .
6. Use after scope
The pointer points to a range variable , Variables become invalid after the range exits , But this pointer is used .
volatile int *p = 0;
int main() {
{
int x = 0;
p = &x;
}
*p = 5;
return 0;
}This code is C++
=================================================================
==3922==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffecd93f880 at pc 0x5616c0570de0 bp 0x7ffecd93f850 sp 0x7ffecd93f840
WRITE of size 4 at 0x7ffecd93f880 thread T0
#0 0x5616c0570ddf in main /root/study/cmakeutils/src/main.cpp:10
#1 0x7f2ccf8c3082 in __libc_start_main ../csu/libc-start.c:308
#2 0x5616c0570c0d in _start (/root/study/cmakeutils/build/main+0xdc0d)
Address 0x7ffecd93f880 is located in stack of thread T0 at offset 32 in frame
#0 0x5616c0570cd8 in main /root/study/cmakeutils/src/main.cpp:5
This frame has 1 object(s):
[32, 36) 'x' (line 7) <== 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, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
...This code is Bash
The first 4 Line shows WRITE( Write memory ) The location of ,*p = 5;
The first 12 Line shows the position of the variable ,int x = 0;
here x The scope of {} Inside , because *p = 5 stay {} Outside , therefore x It doesn't work .
7. Memory leaks
Memory leak , Applied for release .
void *p;
int main() {
p = malloc(7);
p = 0; // The memory is leaked here.
return 0;
}This code is C++
=================================================================
==4076==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x7f799fcff527 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x55a10f15acfa in main /root/study/cmakeutils/src/main.cpp:6
#2 0x7f799f482082 in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s).This code is Visual Basic
The first 6 Line shows the location of the memory request ,p = malloc(7);
The first 9 Line shows the total memory leak .
summary
Write memory safe code , It is a long-term and difficult problem , because C/C++ Not a memory safe language , So such problems will often be encountered .AddressSanitizer Appearance , Make relevant bug The positioning and difficulty of solving problems have been reduced , And accelerate the progress of the project .
边栏推荐
- Abnova 免疫组化服务解决方案
- Stack and queue-p79-10 [2014 unified examination real question]
- Data of all class a scenic spots in China in 2022 (13604)
- 服装门店如何盈利?
- ip地址那点事
- LM small programmable controller software (based on CoDeSys) Note 23: conversion of relative coordinates of servo motor operation (stepping motor) to absolute coordinates
- 请教一下,监听pgsql ,怎样可以监听多个schema和table
- Can't you really do it when you are 35 years old?
- Stack and queue-p78-8 [2011 unified examination true question]
- [GNN] graphic gnn:a gender Introduction (including video)
猜你喜欢

MySQL的安装

基于JS的迷宫小游戏

jdbc数据库连接池使用问题

How to share the same storage among multiple kubernetes clusters

Bus消息总线

Which foreign language periodicals are famous in geology?

SolidWorks GB Library (steel profile library, including aluminum profile, aluminum tube and other structures) installation and use tutorial (generating aluminum profile as an example)

Several index utilization of joint index ABC

LM11丨重构K线构建择时交易策略

dolphinscheduler3. X local startup
随机推荐
How can I check the DOI number of a foreign document?
Learning notes | data Xiaobai uses dataease to make a large data screen
关于数据库数据转移的问题,求各位解答下
js装饰器@decorator学习笔记
Stack and queue-p79-10 [2014 unified examination real question]
Prompt for channel security on the super-v / device defender side when installing vmmare
Can 7-day zero foundation prove HCIA? Huawei certification system learning path sharing
多学科融合
Can't you really do it when you are 35 years old?
BindingException 异常(报错)处理
Config分布式配置中心
from . onnxruntime_ pybind11_ State Import * noqa ddddocr operation error
精准时空行程流调系统—基于UWB超高精度定位系统
.net core 访问不常见的静态文件类型(MIME 类型)
MOS管参数μCox得到的一种方法
C interview encryption program: input plaintext by keyboard, convert it into ciphertext through encryption program and output it to the screen.
Distributed ID solution
Abnova 体外转录 mRNA工作流程和加帽方法介绍
地质学类比较有名的外文期刊有哪些?
Basic introduction of JWT