一、它能抓到什么
// 数据竞争(Data Race)—— 无锁编程最常见的 Bug
int shared_counter = 0;
void worker() {
for (int i = 0; i < 100000; i++) {
shared_counter++; // 不是原子的!多个线程同时写
}
}
void test_race() {
std::thread t1(worker);
std::thread t2(worker);
t1.join();
t2.join();
// 最终结果不一定是 200000,且 TSan 会报告数据竞争
}
TSan 的输出:
WARNING: ThreadSanitizer: data race
Write of size 4 at 0x7f1234567890 by thread T2:
#0 worker() test.cpp:5 (test+0x...)
Previous write of size 4 at 0x7f1234567890 by thread T1:
#0 worker() test.cpp:5 (test+0x...)
Location is global 'shared_counter' at 0x7f1234567890
二、用法
g++ -fsanitize=thread -g -O1 -o test test.cpp
./test
三、TSan 的限制
1. 要求所有代码(含第三方静态库)都加 -fsanitize=thread 编译。
如果一个 .a 文件没有 TSan 检测,里面即使有 race 也检测不到。
2. 不能和 ASan 同时使用(TSan 用 shadow memory 检测 race,ASan 也用它检测越界)。
3. 运行速度慢约 5-10 倍。
4. 假阳性:有些"逻辑上不会出问题"的数据竞争也会被报告。
比如你的 SPSC 队列中,生产者和消费者操作不同变量但在同一缓存行,
TSan 可能因为同一缓存行的两个不同变量而报 false positive。