c++ TSan(Thread Sanitizer)线程检测工具

环境

    Centos 6.0,gcc7.2;

安装

    就不多说了,我是直接用的并没有安装,不过看lib的目录应该是gcc自带的库,export LD_LIBRARY_PATH到gcc下的lib64即可。

作用:

    帮助检查多线程项目中的有可能出现跟线程相关的问题。比如(data races,deadlock,and so on)。

官方文档:

    https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual

    官方常见错误文档如下:https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces

    官方文档,发现错误,但是因为种种原因改不了如下: https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions

    官方常见警告解释如下:https://github.com/google/sanitizers/wiki/ThreadSanitizerReportFormat

    以上就是所有的官方文档,其实细心的同学都会发现只要记住第一个文档即可。

使用:

    该工具需要连接库,指定好LD_LIBRARY_PATH后,在编译参数上加入-ltsan -fsanitize=thread即可。然后运行,就会以warning的形式报告有问题的地方。

    一般我们都是写好了工程之后才会使用这个工具检测是否有问题。第一次对工程使用tsan检测的时候,一般都会出现大量奇奇怪怪的警告。这个时候我们就需要按层级改。所以改之前,需要熟读压制警告:

    其实也很简单就是设置环境变量:export TSAN_OPTIONS="suppressions=压制警告文件目录",然后在压制警告文件中写入:

    简单规则,#开头的都是注释。race:namespace::className::functionName即可,不用带括号。这样可以屏蔽一些特别复杂的问题。以后再改。

主要问题:

data race:

    报告会告诉你read线程的函数栈,在栈顶的哪个函数的哪个地址被读了多少个字节,write函数的函数栈,在栈顶的哪个函数的哪个地址被读了多少个字节,并且告诉你两个线程都是由哪些线程创建的。总结会告诉你到底是哪里有data race的问题。

   大体上的问题就是1. 两个线程同时对一个变量写或者读写,2. 线程1还在用这个变量,但这个变量属于线程2,线程2析构掉了。

        对于问题1,只需要想办法把变量改成原子变量即可;对于问题2,是线程同步的问题,想办法让线程2等待线程1用完了再退出掉。

destroy a locked mutex:

        一般这种问题不会引人注意,但是这样做确实是不对的。更好的做法是在设计上改掉这种摧毁加锁的锁这种情况。我的做法是在锁析构之前判断该锁是否BUSY,如果BUSY则解锁,如果空闲,c++11之前的trylock会直接加锁,而11之后包括11版本不会对trylock进行加锁。

unlock an unlocked mutex:

         二次解锁问题。正常情况下这种解锁一个已经解锁的锁并不会出错,但是这种行为是未定义的,所以不同的c++会有不同的做法,所以还得尽量的避免这种情况。

函数栈提示:failed to restore stack.

        这种情况一般可以用history_size=7搞定,这个东西也设置在TSAN_OPTIONS里,如果TSAN_OPTIONS里需要设置两种,中间用空格隔开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值