当前位置:网站首页>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 .
边栏推荐
- 请教一下,监听pgsql ,怎样可以监听多个schema和table
- 【从零开始】win10系统部署Yolov5详细过程(CPU,无GPU)
- Stack and queue-p79-10 [2014 unified examination real question]
- ESXI挂载移动(机械)硬盘详细教程
- 带你刷(牛客网)C语言百题(第一天)
- 大咖云集|NextArch基金会云开发Meetup来啦
- Kotlin之 Databinding 异常
- 地质学类比较有名的外文期刊有哪些?
- Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
- MYSQL binlog相关命令
猜你喜欢
随机推荐
How to install swoole under window
多学科融合
工具类:对象转map 驼峰转下划线 下划线转驼峰
Etcd database source code analysis -- starting from the start function of raftnode
品牌·咨询标准化
Which foreign language periodicals are famous in geology?
[start from scratch] detailed process of deploying yolov5 in win10 system (CPU, no GPU)
Abnova 膜蛋白脂蛋白体技术及类别展示
Leetcode T1165: 日志分析
dolphinscheduler3. X local startup
MATLAB小技巧(29)多项式拟合 plotfit
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
ip地址那点事
SolidWorks的GB库(钢型材库,包括铝型材、铝管等结构)安装及使用教程(生成铝型材为例)
[GNN] graphic gnn:a gender Introduction (including video)
This article introduces you to the characteristics, purposes and basic function examples of static routing
JWT的基础介绍
【从零开始】win10系统部署Yolov5详细过程(CPU,无GPU)
Take you to brush (niuke.com) C language hundred questions (the first day)
ESXI挂载移动(机械)硬盘详细教程