升级到G++4.8-exception_ptr.h不支持异常传播



我正试图用g++4.8重新编译一个巨大的遗留应用程序,以便调试glibc detected memory corruption问题(使用AddressSanitizer)。以前我们使用g++4.4.7。

但是,编译失败:

/opt/rh/devtoolset-2/root/usr/include/c++/4.8.2/bits/exception_ptr.h:40:4: error: #error This platform does not support exception propagation.

编译自定义异常处理程序时(我想)。自定义异常处理程序只在一个地方使用exception_ptr

void reportOtherException(void) const
{
std::exception_ptr p = std::current_exception();
std::string s = (p != 0 ? p.__cxa_exception_type()->name() : "null");
printf("DvMain Bad Exception: '%s'n", s.c_str());
mErrorReporter(0, DvLog::WARNING, 0, Dv::NO_PROFILE, 0, DvLog::UNHANDLED_OTHER_EXCEPTION);
}

reportOtherException()是这样使用的:

try
{
// Catch and log uncaught exceptions, then exit.
catch (const std::bad_exception& e) { exHandler.reportBadException(e);      }
catch (const std::exception& e)     { exHandler.reportStandardException(e); }
catch (...)                         { exHandler.reportOtherException();     }
}

我对C++还很陌生,甚至不知道这个错误意味着什么。适用于4.4.7,不适用于4.8。

有什么需要修改才能在4.8上编译的指针吗?

编辑I

以下是一些附加信息:

g++ --version
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)

最小代码

DvComDefaultExceptionHandler_test.h

#include "DvCommon.h"
#include "evt/DvEvt.h"
#include "log/DvLog.h"
#include "com/DvComErrorReporter.h"
#include <new>
#include <exception>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <bits/exception_ptr.h>
class DvComDefaultExceptionHandler
{
public:
DvComDefaultExceptionHandler(const DvComErrorReporter& er) {}
~DvComDefaultExceptionHandler() {   }
void reportOtherException(void) const
{
std::exception_ptr p = std::current_exception();
}
private:
static const DvComDefaultExceptionHandler*  mpInstance;
};

DvComDefaultExceptionHandler_test.cpp

#include "DvCommon.h"
#include "com/DvComDefaultExceptionHandler_test.h"

// Pointer to the single instance of the DvComDefaultExceptionHandler class.
const DvComDefaultExceptionHandler*
DvComDefaultExceptionHandler::mpInstance = 0;

编译命令并输出

g++ -c -g -O0  -DDEBUG -Wall -Wextra -Wno-sign-compare -Wcast-align 
--ftemplate-depth-32 -march=native -ggdb -fPIC -Iinclude -I../../include 
-I../../src -I/usr/include/libxml2 -D_GNU_SOURCE   
-I/mnt/swdevel/DVMon/source_build/ext/ACE -D__ACE_INLINE__ 
-I/usr/local/include -I/usr/lib/qt-3.3/include 
-o DvComDefaultExceptionHandler.o DvComDefaultExceptionHandler_test.cpp
In file included from ../../include/com/DvComDefaultExceptionHandler_test.h:76:0,
from DvComDefaultExceptionHandler_test.cpp:13:
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.2/bits/exception_ptr.h:40:4: error: #error This platform does not support exception propagation.
#  error This platform does not support exception propagation.

编辑II

通过include文件进行跟踪可以归结为__GCC_ATOMIC_INT_LOCK_FREE的值。运行此简单程序将'2'打印为__GCC_ATOMIC_INT_LOCK_FREE的值。

int
main(int argc, char **argv)
{
printf("__GCC_ATOMIC_INT_LOCK_FREE = %dn", __GCC_ATOMIC_INT_LOCK_FREE);
}

G++版本:

$ g++ --version
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)

编辑II

我用g++6.3.1尝试过,在Centos 7虚拟机上运行。还是同样的问题。

源文件-仅一行

#include <bits/exception_ptr.h>

编译命令:g++ -c -o test.o test.cpp

首先,直接包含<bits/exception_ptr.h>在技术上是不受支持的。它在头文件中是这么说的。这在GCC 4.4中或多或少是偶然发生的。此头文件的C++11迁移破坏了它,因为由于命名空间的原因,C++98代码无法使用ATOMIC_INT_LOCK_FREE宏,并且头不再工作。

在GCC 7中,这是作为这个错误的一部分修复的(再次意外):

  • std::future手臂骨折

直接包含<bits/exception_ptr.h>的技巧应该在这个版本中再次奏效。

这意味着你的选择是:

  1. 以C++11或更高版本的模式编译代码(建议使用带有GCC 6的C++14)
  2. 如果GCC 7可用,请升级到DTS 7,它具有重新启用C++98破解的上游修复程序
  3. std::exception_ptr的使用封装在不透明类型中,以C++11或更高版本的模式编译其实现,并将系统的其余部分保持在C++98模式中
  4. 使用另一个破解,也许像这样:

    #include <exception>
    #ifndef ATOMIC_INT_LOCK_FREE
    # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
    #endif
    #include <bits/exception_ptr.h>
    

    同样,这是完全不受支持的,但它不应该比你今天拥有的(GCC 4.4)更糟糕

我能够使用带有gcc 4.8.2的码头化Centos6重现您的问题。在将开发工具升级到版本6(gcc 6.3.1)后,您的代码编译没有任何问题。尝试使用以下步骤升级开发工具(建议仅用于测试):

  • 通过添加文件/etc/yum.repos.d/devtools-sclo.repo:添加sclo-centos6存储库

    [testing-devtools]
    name=devtools multiple for CentOS 
    baseurl=http://mirror.centos.org/centos/6/sclo/x86_64/rh/
    gpgcheck=0
    
  • 安装devtoolset-6软件包:

    百胜安装devtoolset-6-binutils devtoolset6-gcc-++

  • 将bash环境设置为新版本:

    scl启用devtoolset-6 bash

现在尝试重新编译您的基本示例和完整源代码。

注意:这个存储库还包含devtoolset-3和devtoolset-4的包。如果需要的话,很容易尝试。

相关内容

最新更新