簡介
谷歌有一系列Sanitizer工具,可用于排查程序中內存相關的問題。常用的Sanitizer工具包括:
- Address Sanitizer(ASan):用于檢測內存使用錯誤。
- Leak Sanitizer(LSan):用于檢測內存泄漏。
- Thread Sanitizer(TSan):用于檢測多線程間的數據競爭和死鎖。
- Memory Sanitizer(MSan):用于檢測使用未初始化內存的行為。
本文重點介紹ASan工具的使用。
ASAN工具作用
ASan工具可以檢測出程序不可理使用內存的行為,主要包括:
注:ASan內部包含LSan,故ASan也可以用來檢測內存泄漏相關問題。
ASAN工具原理
- 在編譯時,ASan會替換malloc/free接口;
- 在程序申請內存時,ASan會額外分配一部分內存(影子內存)來標識改內存的狀態;
- 在程序使用內存時,ASan會額外進行判斷,確認該內存是否可以被訪問,并在訪問異常時給出錯誤信息。
ASAN工具安裝
ASan已經集成在GCC 4.8中,但GCC 4.9及以上版本才支持 Address Sanitizer 的所有功能。
可知,當前GCC版本已支持ASan,故無須再安裝。
ASAN工具使用
GCC編譯選項
-fsanitize=address:開啟內存越界檢測;
-fsanitize-recover=address:一般后臺程序為保證穩定性,不能遇到錯誤就簡單退出,而是繼續運行,采用該選項支持內存出錯之后程序繼續運行,需要疊加設置ASAN_OPTIONS=halt_on_error=0才會生效;若未設置此選項,則內存出錯即報錯退出;
-fno-stack-protector:去使能棧溢出保護;
-fno-omit-frame-pointer:去使能棧溢出保護
ASAN調試示例
測試示例一
測試程序
1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>4 5 void func(void)6 {7 char* str = NULL;8 memcpy(str, "test", sizeof("test"));9 }10 11 int main(void)12 {13 printf("hello world!\n");14 15 func();16 17 return 0;18 }
按如下方式編譯,并執行測試
lx@lx-virtual-machine:~/asan$ gcc main.c -fsanitize=address -fsanitize-recover=address -fno-stack-protector -fno-omit-frame-pointer
lx@lx-virtual-machine:~/asan$
lx@lx-virtual-machine:~/asan$ ./a.out
hello world!
ASAN:DEADLYSIGNAL
=================================================================
==6880==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x7fd7df251255 bp 0x7ffc24aea420 sp 0x7ffc24ae9b88 T0)
==6880==The signal is caused by a WRITE memory access.
==6880==Hint: address points to the zero page.#0 0x7fd7df251254 (/lib/x86_64-linux-gnu/libc.so.6+0xbb254)#1 0x7fd7df6006ce (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x796ce)#2 0x5637740ca9b1 in func (/home/lx/asan/a.out+0x9b1)#3 0x5637740ca9c9 in main (/home/lx/asan/a.out+0x9c9)#4 0x7fd7df1b7c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)#5 0x5637740ca8a9 in _start (/home/lx/asan/a.out+0x8a9)AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0xbb254)
==6880==ABORTING
可知,測試結果符合分析預期。
參考
https://blog.csdn.net/qq_15437629/article/details/114440930