捕获派生异常类型在 Clang/MacOS X 上失败
Catching derived exceptions types fails on Clang/MacOS X
我有一个C++库,我正在尝试使用Clang在Mac OS X上运行。该库由一个 DLL 和一个单元测试可执行文件组成。它使用 GCC 和 MSVC 编译得很好,使用 GCC,我使用以下设置:
- 该库使用
-fvisibility=hidden
编译 - 所有公开的类都显式标记为
__attribute__(visibility("default"))
- 该库有一些异常类,派生自
std::runtime_error
。所有此类类都标记为默认可见性。有一个根类LibraryException
从中派生更具体的异常。 - 在 GCC 上,我使用
-std=c++0x
,带有 clang,库和单元测试可执行文件都是用-stdlib=libc++ -std=c++11
构建
的
在 Mac OS X 上,单元测试框架现在失败,因为异常类型错误。 即这样的测试失败:
// bla.foo () throws CustomException, which is derived from LibraryException
TEST_THROWS (bla.foo (), CustomException)
// This works however
TEST_THROWS (bla.foo (), LibraryException)
我验证了我的自定义异常类的 typeinfo 和 vtable 是否使用 nm -g library.dylib | c++filt -p -i
导出。似乎所有例外情况都是如此...这到底是怎么回事?我试图对错误的进行调试,我看到如何在库中抛出正确的类型,但单元测试可执行文件中无法捕获相同的类型。Clang有什么特别的要求才能使它工作吗?我正在使用SVN最新的googletest框架进行测试。
一个小型测试程序也表现出同样的问题:
try {
funcThatThrowsCustomExceptionFromLibraryDylib ();
} catch (CustomException& e) {
// doesn't get here
} catch (LibraryException& e) {
// does get here
// after demangle, this prints CustomException
// Can cast down to CustomException and access the fields as well
std::cout << typeid (e).name () << "n";
}
例如,当从库中引发boost::lexical_cast
异常时,它也失败。
这是正确的解决方案:
应用可见性属性时,必须在编译库时以及使用库时应用该属性。否则,客户端将看不到这些类。对于 boost::lexical_cast,这意味着您必须使用
#pragma GCC visibility push(default)
#include <boost/lexical_cast.hpp>
#pragma GCC visibility pop
直到他们通过在异常中添加__attribute((visibility("default")))
在库中修复它(从 Boost 1.50 开始,该属性存在,但似乎还没有对 Clang 的支持)。在库中的标头中使用它时,可以在客户端代码中正确捕获它。这个#pragma
也适用于Clang。
指定抛出 () 析构函数这一事实有所帮助,但这绝对不是正确的解决方案。
相关文章:
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- node-gyp 在 macOS 上未正确链接库
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 链接器命令失败,macOS 上的退出代码为 1(使用 -v 查看调用)
- 在 macOS 上的 CLion 中导入 Bazel 项目失败
- Xcode OSX上的C++构建失败,出现多个错误文件IO..不可用:在macOS 10.15中引入
- Unity webGL - MacOS 上的构建项目失败
- 捕获派生异常类型在 Clang/MacOS X 上失败
- MacOS Sierra - cmake使用qt5失败