文档目录

一、它能抓到什么

// 数据竞争(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。