【发布时间】:2012-06-02 23:43:37
【问题描述】:
我知道,这个问题已经被问过很多次了,但是我找不到我的问题的解决方案。
我有以下情况:
A
/ \
/ \
B <-- C
- A 是一个共享库,其中包含类
EException - B 和 C 链接到 A
- C 也是一个共享库
- B 在运行时动态加载 C
在某些时候,C 抛出了一个 EException 的实例:
void doSometing() {
throw EException("test-message");
}
在B 我想捕捉这个异常:
try {
doSomething();
} catch (const EException& ex) {
// Not reached
} catch (...) {
// Not reached
}
但正如代码中所提到的,没有一个 catch 子句被调用。相反,执行此代码的线程被中止。
我尝试了以下方法:
- 编译A时
EException的可见性属性设置为“默认” -
EException头文件仅包含声明 - 我在 A、B 和 C 中使用链接器选项
-fvisibility=hidden - 我在 C 中使用链接器选项
-E
使用nm 我得到A:
0000000000066260 T EException::EException(QString const&)
0000000000066306 T EException::EException(EException const&)
00000000000661d0 T EException::EException()
0000000000066260 T EException::EException(QString const&)
0000000000066306 T EException::EException(EException const&)
00000000000661d0 T EException::EException()
00000000000664de T EException::~EException()
000000000006641e T EException::~EException()
000000000006641e T EException::~EException()
00000000000663b6 T EException::operator=(EException const&)
<...>
000000000028de40 V typeinfo for EException
000000000028dd80 V typeinfo for EException*
000000000007342b V typeinfo name for EException
0000000000072ab7 V typeinfo name for EException*
000000000028de00 V vtable for EException
对于B:
U EException::EException(QString const&)
U EException::~EException()
<...>
0000000000726f60 V typeinfo for EException
对于C:
U EException::EException(QString const&)
U EException::~EException()
<...>
U typeinfo for EException
问题可能是,B 使用自己的类型信息EException,而C 使用A 提供的类型信息?我该如何解决这个问题?
我的环境:
- x86_64-linux-gnu 上的 gcc 4.6.3
- 使用 Qt
感谢您的帮助!
【问题讨论】:
-
catch(...)似乎并不意味着您的错误与您的异常类本身(或其 ctor 中的错误)无关。您是否尝试过调试它并查看该投掷线上会发生什么? -
在 throw 行上,
EException的复制构造函数被调用。复制构造函数中没有错误,并且在它完成后线程中止。 -
另见 GCC 常见问题解答中的 dynamic_cast, throw, typeid don't work with shared libraries。它告诉您避免
-Bsymbolic链接器选项,并使用-E链接器选项。我也猜测B应该使用--exclude-libs ALL。
标签: c++ exception-handling g++ shared-libraries