Gtest使用C++11 std::condition_variable表示valgrind错误



如果我用谷歌测试框架这样写测试:

TEST_F( TestFName, TestName )
{
std::condition_variable cv;
}

它会产生一个valgrind错误。我用--leak-check=full --track-origins=yes选项运行它。

Conditional jump or move depends on uninitialised value(s)
==17215==    at 0x4E3DA82: pthread_cond_destroy@@GLIBC_2.3.2 (pthread_cond_destroy.c:35)
...
Uninitialised value was created by a stack allocation
==17215==    at 0x4551D0: TestFName_TestName_test::TestBody()

奇怪的是,意识到错误来自condition_variable cv声明。当我将其声明为全局时,错误就消失了。

我在一台装有Ubuntu 3.8 x86_64的机器上运行Valgrind-3.7.0。

其他人遇到了同样的问题吗?

根据对源代码的阅读,我的猜测是您的编译环境与用于编译您正在使用的libstdc++二进制文件的环境不匹配。具体来说,libstdc++是在没有_GTHREAD_USE_COND_INIT_FUNC的情况下编译的,它是在您的环境中定义的。

原因如下:报头<condition_variable>定义了解析为pthread_cond_t的类型的数据成员。如果定义了宏__GTHREAD_COND_INIT,则在头中指定该成员的默认初始化,在实现文件中默认构造函数。如果不是,则使用非默认构造函数体中的函数调用对其进行初始化。是否定义__GTHREAD_COND_INIT_GTHREAD_USE_COND_INIT_FUNC宏控制。

如果类内成员初始化是以我认为的方式在G++中实现的,例如,类内初始化程序是在调用构造函数之前执行的,那么当您的libstdc++是用未定义的_GTHREAD_USE_COND_INIT_FUNC编译的,而现在它是在您的环境中的某个地方定义的时,您会看到这种效果。这意味着标头不提供类内初始化,而是使用库中的默认构造函数,从而导致未初始化的值。

来源参考,如果你想深入挖掘:

  • https://github.com/mirrors/gcc/blob/master/libstdc%2B%2B-v3/include/std/condition_variable
  • https://github.com/mirrors/gcc/blob/master/libstdc%2B%2B-v3/src/c%2B%2B11/condition_variable.cc
  • https://github.com/mirrors/gcc/blob/master/libgcc/gthr.h
  • https://github.com/mirrors/gcc/blob/master/libgcc/gthr-posix.h

相关内容

最新更新