当前位置:网站首页>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=address
This 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=address
This 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 .
边栏推荐
猜你喜欢
一文带你了解静态路由的特点、目的及配置基本功能示例
如何给目标机器人建模并仿真【数学/控制意义】
[start from scratch] detailed process of deploying yolov5 in win10 system (CPU, no GPU)
学术报告系列(六) - Autonomous Driving on the journey to full autonomy
Several index utilization of joint index ABC
JWT的基础介绍
BindingException 异常(报错)处理
Answer to the first stage of the assignment of "information security management and evaluation" of the higher vocational group of the 2018 Jiangsu Vocational College skills competition
JESD204B时钟网络
Learning notes | data Xiaobai uses dataease to make a large data screen
随机推荐
分布式id解决方案
Go straight to the 2022ecdc fluorite cloud Developer Conference: work with thousands of industries to accelerate intelligent upgrading
Abnova循环肿瘤DNA丨全血分离,基因组DNA萃取分析
String (explanation)
数据资产管理与数据安全国内外最新趋势
算法---比特位计数(Kotlin)
【从零开始】win10系统部署Yolov5详细过程(CPU,无GPU)
华为机试题素数伴侣
Stack and queue-p79-10 [2014 unified examination real question]
SolidWorks的GB库(钢型材库,包括铝型材、铝管等结构)安装及使用教程(生成铝型材为例)
What books can greatly improve programming ideas and abilities?
from . onnxruntime_ pybind11_ State Import * noqa ddddocr operation error
Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
oracle如何备份索引
当前发布的SKU(销售规格)信息中包含疑似与宝贝无关的字
Bus消息总线
MATLAB小技巧(30)非线性拟合 lsqcurefit
MySQL view bin log and recover data
FPGA课程:JESD204B的应用场景(干货分享)
Unable to debug screen program with serial port