zoukankan      html  css  js  c++  java
  • 使用ThreadSanitizer线程检查工具

    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(如果不是请重编)
  • 相关阅读:
    cuda基础----流
    cuda基础---异步并行执行
    cuda基础---cuda通信机制
    cuda基础-----cuda编程模型/软件体系/存储器模型
    大顶堆 小顶堆应用----中位数查找
    Maven配置阿里云镜像
    C++中bool型变量按位取反总是为true
    区分C++的继承、覆盖、隐藏、重载
    C++Primer第5章 语句
    C++Primer第4章 表达式
  • 原文地址:https://www.cnblogs.com/coderzh/p/ThreadSanitizer.html
Copyright © 2011-2022 走看看