繁体   English   中英

使用Clang而不是GCC构建(可疑)示例时出现内存损坏

[英]Memory corruption when building (questionable) example with Clang instead of GCC

我有一些C代码,这些代码早在几年前就被快速“转换”为C ++代码,现在我维护它们。 在不同的操作系统上运行它并使用不同的编译器进行构建时,我注意到了一些特殊的行为,并且可以使用一些帮助来诊断我最近解决的一些问题。


该代码在以下系统上运行没有问题:

  • Ubuntu 14.04.2 LTS x64
  • GCC 4.8.4

将其移植到以下系统后,一切就结束了:

  • OSX“ El Capitan”
  • Apple LLVM版本7.3.0(clang-703.0.29)

令人反感的代码围绕以下结构展开:

struct blk_data {
    int i;
    int s;
    boost::mutex protectionMutex;
};

有一段代码通过malloc()创建此POD的动态实例(普通旧数据,无自定义方法或构造函数等malloc()

struct blk_data* pData = (blk_data*)malloc(16 * sizeof(struct blk_data));
if ( pData )
//...

请忽略我强制转换malloc()结果的事实。 如果没有,编译器会标记错误。

稍后在代码中,我调用:

boost::unique_lock<boost::mutex> tempLock(pData->protectionMutex);

对于带有GCC的Linux,没有问题。 使用OSX和Clang,程序会出错,并指出最终传递给pthread_mutex_lock()的互斥锁地址无效。 最终,我能够通过以下方式解决此问题:

  • 使用new代替malloc()
  • 设置${CXXFLAGS} += -std=c++11

其中,类似的问题会弹出一个第二个案例是使用代码块new ,但随后memset荷兰国际集团的结构。 据我了解,只要使用POD struct ,这是安全的。

为什么此代码可以在GCC / Linux上构建并正常运行,却可以构建但不能运行; 在Clang / OSX上? 难道一个struct不再算作一个POD struct ,如果它包含RAII风格的成员,或已经违反了我的全部时间的C ++标准的一部分(即:未定义行为)? 还是在Clang vs GCC中进行了更严格的检查?

谢谢。

malloc的文档中:

分配未初始化存储的大小字节

因此,在初始化之前使用内存是不确定的行为。

它可以在GCC中工作,因为 运气好 glibc的实现细节,特别是glibc的malloc依赖于调用nmap从系统分配新内存这一事实。 默认情况下,nmap将内存归零,以防止信息从一个进程泄漏到另一个进程。

此处的文档: http : //man7.org/linux/man-pages/man2/mmap.2.html

OSX的malloc有所不同(尽管文档并未明确是否初始化新​​内存): https : //developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/malloc.3.html

尽管我不确定boost::mutex是否为POD,但malloc仅分配内存,而不初始化对象,这使protectionMutex未初始化。

尽管new确保了boost::mutex默认ctor被调用,并因此初始化了protectionMutex

[更新]检查boost互斥体的头文件 ,它在内部使用指针:

#if defined(BOOST_HAS_WINTHREADS)
    typedef void* cv_state;
#elif defined(BOOST_HAS_PTHREADS)
    struct cv_state
    {
        pthread_mutex_t* pmutex;
    };
#elif defined(BOOST_HAS_MPTASKS)
    struct cv_state
    {
    };
#endif

因此, malloc当然不会初始化指针,而new会初始化。

但是我真的不知道为什么GCC可以工作...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM