ThreadSanitizer又叫TSan,是一个检查线程Data Race的C/C++工具。它集成在新版的gcc和clang中,通过编译时加-fsanitize=thread,可以用来在运行时检测出Data Race的问题。同样的工具还有valgrind的helgrind,但是TSan性能比helgrind要好。
Data Race
Data Race是指多个线程在没有正确加锁的情况下,同时访问同一块数据,并且至少有一个线程是写操作,对数据的读取和修改产生了竞争,从而导致各种不可预计的问题。
Data Race的问题非常难查,Data Race一旦发生,结果是不可预期的,也许直接就Crash了,也许导致执行流程错乱了。
sample代码
clang -fsanitize=thread -g -O0 -fPIE -pie -o main main.c
编译:
ubuntu@ubuntu-nvidia:~/proj/threadsan$ ./main
1
Thread T2 (tid=11592, running) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:22:3 (main+0xb8c20)
Thread T1 (tid=11591, finished) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:21:3 (main+0xb8bfc)
SUMMARY: ThreadSanitizer: data race /home/ubuntu/proj/threadsan/main.c:12:10 in Thread2
==================
2
==================
WARNING: ThreadSanitizer: data race (pid=11589)
Write of size 4 at 0x005556133198 by main thread:
#0 main /home/ubuntu/proj/threadsan/main.c:23:10 (main+0xb8c38)
Previous write of size 4 at 0x005556133198 by thread T1:
#0 Thread1 /home/ubuntu/proj/threadsan/main.c:6:10 (main+0xb8ae8)
Location is global 'Global' of size 4 at 0x005556133198 (main+0x000000bde198)
Thread T1 (tid=11591, finished) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:21:3 (main+0xb8bfc)
SUMMARY: ThreadSanitizer: data race /home/ubuntu/proj/threadsan/main.c:23:10 in main
==================
ThreadSanitizer: reported 2 warnings
### 运行时出现的检测出来的log
ubuntu@ubuntu-nvidia:~/proj/threadsan$ ./main
1
Thread T2 (tid=11592, running) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:22:3 (main+0xb8c20)
Thread T1 (tid=11591, finished) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:21:3 (main+0xb8bfc)
SUMMARY: ThreadSanitizer: data race /home/ubuntu/proj/threadsan/main.c:12:10 in Thread2
==================
2
==================
WARNING: ThreadSanitizer: data race (pid=11589)
Write of size 4 at 0x005556133198 by main thread:
#0 main /home/ubuntu/proj/threadsan/main.c:23:10 (main+0xb8c38)
Previous write of size 4 at 0x005556133198 by thread T1:
#0 Thread1 /home/ubuntu/proj/threadsan/main.c:6:10 (main+0xb8ae8)
Location is global 'Global' of size 4 at 0x005556133198 (main+0x000000bde198)
Thread T1 (tid=11591, finished) created by main thread at:
#0 pthread_create <null> (main+0x290b4)
#1 main /home/ubuntu/proj/threadsan/main.c:21:3 (main+0xb8bfc)
SUMMARY: ThreadSanitizer: data race /home/ubuntu/proj/threadsan/main.c:23:10 in main
==================
ThreadSanitizer: reported 2 warnings
缺陷:
- deadlock 并不能发现
- 因为是运行中检测的,代码没有跑到的话,就不会检测出来有问题