当前位置:网站首页>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 .
边栏推荐
- [GNN] graphic gnn:a gender Introduction (including video)
- ANR 原理及实践
- 循环肿瘤细胞——Abnova 解决方案来啦
- Performance comparison between Ceres solver and g2o
- Networkx绘图和常用库函数坐标绘图
- 地质学类比较有名的外文期刊有哪些?
- 2018年江苏省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书第一阶段答案
- Mysql---- import and export & View & Index & execution plan
- MYSQL binlog相关命令
- FPGA课程:JESD204B的应用场景(干货分享)
猜你喜欢
MySQL installation
学术报告系列(六) - Autonomous Driving on the journey to full autonomy
数据资产管理与数据安全国内外最新趋势
[GNN] graphic gnn:a gender Introduction (including video)
[start from scratch] detailed process of deploying yolov5 in win10 system (CPU, no GPU)
Can't you really do it when you are 35 years old?
jdbc数据库连接池使用问题
服装门店如何盈利?
Learning notes | data Xiaobai uses dataease to make a large data screen
2022 Android interview essential knowledge points, a comprehensive summary
随机推荐
Postgresql中procedure支持事务语法(实例&分析)
二十岁的我4面拿到字节跳动offer,至今不敢相信
Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
带你刷(牛客网)C语言百题(第一天)
从零到一,教你搭建「CLIP 以文搜图」搜索服务(二):5 分钟实现原型
品牌·咨询标准化
MySQL的主从复制原理
联合索引ABC的几种索引利用情况
Linear algebra (1)
多学科融合
请问如何查一篇外文文献的DOI号?
This article introduces you to the characteristics, purposes and basic function examples of static routing
Abnova 免疫组化服务解决方案
FPGA课程:JESD204B的应用场景(干货分享)
Networkx绘图和常用库函数坐标绘图
Tkinter window selects PCD file and displays point cloud (open3d)
2018年江苏省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书
Matlab tips (29) polynomial fitting plotfit
C interview encryption program: input plaintext by keyboard, convert it into ciphertext through encryption program and output it to the screen.
mysql查看bin log 并恢复数据