升级到 G++ 4.8 - exception_ptr.h 不支持异常传播
Upgrading to G++ 4.8 - exception_ptr.h Does not support exception propagation
我正在尝试使用 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 上编译需要更改什么的任何指示?
编辑我
这里有一些额外的信息:
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.
编辑二
跟踪包含文件归结为 __GCC_ATOMIC_INT_LOCK_FREE 的值。 运行 这个简单的程序打印“2”作为 __GCC_ATOMIC_INT_LOCK_FREE.
的值
int
main(int argc, char **argv)
{
printf("__GCC_ATOMIC_INT_LOCK_FREE = %d\n", __GCC_ATOMIC_INT_LOCK_FREE);
}
G++ 版本:
$ g++ --version
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
编辑二
我已经在 Centos 7 VM 上用 g++ 6.3.1 运行 试过了。还是一样的问题。
源文件 - 仅一行
#include <bits/exception_ptr.h>
编译命令:g++ -c -o test.o test.cpp
我能够使用 dockerized Centos6 和 gcc 4.8.2 重现您的问题。将开发工具升级到版本 6 (gcc 6.3.1) 后,您的代码编译没有任何问题。尝试使用以下步骤升级开发工具(仅建议用于测试):
通过添加文件添加 sclo centos6 存储库 /etc/yum.repos.d/devtools-sclo.repo :
[testing-devtools]
name=devtools multiple for CentOS
baseurl=http://mirror.centos.org/centos/6/sclo/x86_64/rh/
gpgcheck=0
安装 devtoolset-6 软件包:
yum 安装 devtoolset-6-binutils devtoolset-6-gcc-c++
将bash环境设置为新版本:
scl 启用 devtoolset-6 bash
现在尝试重新编译您的基础示例和完整源代码。
注意:这个存储库也包含 devtoolset-3 和 devtoolset-4 的包。如果需要,非常容易尝试。
首先,技术上不支持直接包含<bits/exception_ptr.h>
。它在头文件中是这么说的。这或多或少是偶然在 GCC 4.4 中起作用的。这个头文件的 C++11 迁移破坏了它,因为命名空间的原因,C++98 代码不能使用 ATOMIC_INT_LOCK_FREE
宏,头文件不再工作。
在 GCC 7 中,这已作为此错误的一部分修复(再次意外):
直接包含 <bits/exception_ptr.h>
的技巧在此版本中应该再次起作用。
这意味着您的选择是:
- 在 C++11 或更高版本的模式下编译您的代码(推荐使用带有 GCC 6 的 C++14)。
- 当 GCC 7 可用时升级到 DTS 7,它具有重新启用 C++98 hack 的上游修复程序。
- 将
std::exception_ptr
的使用包装在一个不透明类型中,在 C++11 或更高版本的模式下编译其实现,并在 C++98 模式下保留系统的其余部分。
使用另一种 hack,也许像这样:
#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)差多少。
我正在尝试使用 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 上编译需要更改什么的任何指示?
编辑我
这里有一些额外的信息:
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.
编辑二
跟踪包含文件归结为 __GCC_ATOMIC_INT_LOCK_FREE 的值。 运行 这个简单的程序打印“2”作为 __GCC_ATOMIC_INT_LOCK_FREE.
的值int
main(int argc, char **argv)
{
printf("__GCC_ATOMIC_INT_LOCK_FREE = %d\n", __GCC_ATOMIC_INT_LOCK_FREE);
}
G++ 版本:
$ g++ --version
g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
编辑二
我已经在 Centos 7 VM 上用 g++ 6.3.1 运行 试过了。还是一样的问题。
源文件 - 仅一行
#include <bits/exception_ptr.h>
编译命令:g++ -c -o test.o test.cpp
我能够使用 dockerized Centos6 和 gcc 4.8.2 重现您的问题。将开发工具升级到版本 6 (gcc 6.3.1) 后,您的代码编译没有任何问题。尝试使用以下步骤升级开发工具(仅建议用于测试):
通过添加文件添加 sclo centos6 存储库 /etc/yum.repos.d/devtools-sclo.repo :
[testing-devtools] name=devtools multiple for CentOS baseurl=http://mirror.centos.org/centos/6/sclo/x86_64/rh/ gpgcheck=0
安装 devtoolset-6 软件包:
yum 安装 devtoolset-6-binutils devtoolset-6-gcc-c++
将bash环境设置为新版本:
scl 启用 devtoolset-6 bash
现在尝试重新编译您的基础示例和完整源代码。
注意:这个存储库也包含 devtoolset-3 和 devtoolset-4 的包。如果需要,非常容易尝试。
首先,技术上不支持直接包含<bits/exception_ptr.h>
。它在头文件中是这么说的。这或多或少是偶然在 GCC 4.4 中起作用的。这个头文件的 C++11 迁移破坏了它,因为命名空间的原因,C++98 代码不能使用 ATOMIC_INT_LOCK_FREE
宏,头文件不再工作。
在 GCC 7 中,这已作为此错误的一部分修复(再次意外):
直接包含 <bits/exception_ptr.h>
的技巧在此版本中应该再次起作用。
这意味着您的选择是:
- 在 C++11 或更高版本的模式下编译您的代码(推荐使用带有 GCC 6 的 C++14)。
- 当 GCC 7 可用时升级到 DTS 7,它具有重新启用 C++98 hack 的上游修复程序。
- 将
std::exception_ptr
的使用包装在一个不透明类型中,在 C++11 或更高版本的模式下编译其实现,并在 C++98 模式下保留系统的其余部分。 使用另一种 hack,也许像这样:
#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)差多少。