ThreadSanitizer

Snaitizer家族,還有AddressSanitizer 和 MemorySanitizer


ThreadSanitizer又叫TSan,是一個檢查線程Data Race的C/C++工具。它集成在新版的gcc和clang中,通過編譯時加-fsanitize=thread,可以在運行時檢測出Data Race的問題。

ThreadSanitizer官網:https://code.google.com/p/thread-sanitizer

Data Race

Data Race是指多個線程在沒有正確加鎖的情況下,同時訪問同一塊數據,並且至少有一個線程是寫操作,對數據的讀取和修改產生了競爭,從而導致各種不可預計的問題。

Data Race的問題非常難查,Data Race一旦發生,結果是不可預期的,也許直接就Crash了,也許導致執行流程錯亂了,也許把內存破壞導致之後某個時刻突然Crash了。

環境要求

  1. Linux x86_64,內核版本不要太舊。(經測試,公司舊的開發機Linux內核是2.6.16是跑不了的,新的tlinux內核3.10.0可以)
  2. gcc 4.8版本以上(clang也集成了,3.2版本以上)

官方示例


$ cat simple_race.cc
#include <pthread.h>
#include <stdio.h>
 
int Global;
 
void *Thread1(void *x) {
  Global++;
  return NULL;
}
 
void *Thread2(void *x) {
  Global--;
  return NULL;
}
 
int main() {
  pthread_t t[2];
  pthread_create(&t[0], NULL, Thread1, NULL);
  pthread_create(&t[1], NULL, Thread2, NULL);
  pthread_join(t[0], NULL);
  pthread_join(t[1], NULL);
}



上面的代碼在不加鎖的情況下,兩個線程同時去修改Global變量,從而導致Data Race。使用gcc的-fsanitize=thread 編譯,執行


$ g++ simple_race.cc -fsanitize=thread -fPIE -pie -g
$ ./a.out
==================
WARNING: ThreadSanitizer: data race (pid=26327)
  Write of size 4 at 0x7f89554701d0 by thread T1:
    #0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66)
 
  Previous write of size 4 at 0x7f89554701d0 by thread T2:
    #0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6)
 
  Thread T1 (tid=26328, running) created at:
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
    #1 main simple_race.cc:19 (exe+0x000000006f39)
 
  Thread T2 (tid=26329, running) created at:
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
    #1 main simple_race.cc:20 (exe+0x000000006f63)
==================
ThreadSanitizer: reported 1 warnings

執行程序,如果發生Data Race,錯誤信息會直接輸出出來。如果錯誤信息比較多,重定向輸出流到文件裏,慢慢分析:


$ ./a.out >result.txt 2>&1



關鍵要點

  1. 除了加-fsanitize=thread外,一定要加-fPIE -pie。
  2. -g 是爲了能顯示文件名和行號。
  3. 如果分生成obj(-c)和link兩個步驟,每一步都加:thread -fPIE -pie -g,並且在link的時候加-ltsan
  4. 只支持64位,最好指定編譯64位(-m64)
  5. 如果依賴其他靜態庫,其他靜態庫編譯時必須指定-fPIC(如果不是請重編)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章