spdlog的一些坑


最近在用C++的这个spdlog库中遇到了一些坑……在这里写一下

线程不安全

这个库宣称自己是线程安全的,实际上它做的是:

这里有两个地方不安全

localtime_r

│ctime_r(), │ Thread safety │ MT-Safe env locale │ │gmtime_r(), │ │ │ │localtime_r(), │ │ │ │mktime() │ │ │ ├───────────────┼───────────────┼─────────────────────────────────┤

localtime_r虽然是MT-Safe的,但它对env, locale的读取没有做任何同步措施。因此中途如果另一个线程对env/locale发生了修改,可能会发生各种各样神奇的事故。当然,这个是次要的问题,更主要的问题在下面。

operator «(ostream&, void *const)

大家可能常常觉得只要cout那里锁住了就好,实际上并不如此。上面这段代码用valgrind –tool=drd跑一下就会出现如下警告:

如上所示,即使两个完全不同的ostream的operator « 也有可能发生data race,这就很尴尬了。这是因为在operator«中调用了locale的widen方法,widen方法是怎么实现的呢?下面是libstdc++ 6.2.1 bits/locale_facet.h的实现:

很明显这里没有任何同步措施。这就造成了spdlog坑居多……

正确的做法是什么呢?

待续。。(翻了一圈GTest好像也没有考虑这点……而且也不像是libstdc++的bug……