clang有一個王牌功能是sanitizer。它包含三種:AddressSanitizer、MemorySanitizer、ThreadSanitizer。AddressSanitizer和MemorySanitizer最初是google開發的,用於運行時檢測C/C++程序中的內存錯誤。在編譯的時候加上-fsanitizer參數,編譯器就會在生成的代碼中插入一些運行時檢查。好比你能夠拿下面的這段代碼試下: html
#include <stdio.h> #include <string.h> int main(int argc,char* argv[]){ char buf[4]; strcpy(buf,argv[1]); printf("%s\n",buf); return 0; }
它把命令行的第一個參數複製到一個臨時的緩存區中,而後打印出來。 windows
這段代碼有兩個bug: 緩存
來,編譯試下: 安全
C:>clang++ -fsanitize=address -o t.exe badcode.cpp -g3 -DDEBUG -D_DEBUG app
而後運行: 優化
C:>t 3
3
C:>t 355
355
C:>t 3554664
=================================================================
==4044==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x0024fd44 at
pc 0x1274038 bp 0xdeadbeef sp 0x24fbf0
WRITE of size 8 at 0x0024fd44 thread T0
#0 0x127404c wrap_strcpy c:\users\cm\documents\os\llvm-3.4\projects\compile
r-rt\lib\asan\asan_interceptors.cc:490
#1 0x12612a7 main+0x0x000002a7
#2 0x1278212 __tmainCRTStartup f:\dd\vctools\crt\crtw32\startup\crt0.c:255
#3 0x772d3369 BaseThreadInitThunk+0x0x00000011
#4 0x77ba9f71 RtlInitializeExceptionChain+0x0x00000062
#5 0x77ba9f44 RtlInitializeExceptionChain+0x0x00000035
Address 0x0024fd44 is located in stack of thread T0 at offset 228 in frame
#0 0x126100f main+0x0x0000000f
This frame has 4 object(s):
[32, 36) 」
[96, 100) 」
[160, 164) 」
[224, 228) ‘buf’ <== Memory access at offset 228 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind
mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ??
Shadow bytes around the buggy address:
0x20049f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049f80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x20049f90: 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2
=>0x20049fa0: 04 f4 f4 f4 f2 f2 f2 f2[04]f4 f4 f4 f3 f3 f3 f3
0x20049fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20049ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==4044==ABORTING
它會提早把錯誤檢測出來,並終止程序。 this
可是memory sanitizer目前在windows下還不能用。 google