二元边界上的异常 [英] Exceptions across binary boundary
问题描述
我知道,这个问题已经被问了很多次,但我找不到我的问题的解决方案。
我有以下情况: p>
A
/ \
/ \
B < - C
- A是一个共享库,包含
EException
- B和C链接A
- C是共享库
- B在运行时动态加载C
在某些时候C抛出一个 EException
:
void doSometing(){
throw EException(test-message);
}
在 B
I想要捕获此异常:
try {
doSomething
} catch(const EException& ex){
//未达到
} catch(...){
//未达到
}
但如代码中所述,两个catch子句都不会被调用。
我试过下面的事情:
- 编译A时
EException
的可见性属性设置为default -
EException
头文件仅包含声明 - 我在A中使用链接器选项
-fvisibility = hidden
,B和C - 我在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 $ b 00000000000664de T EException ::〜EException()
000000000006641e T EException ::〜EException()
000000000006641e T EException ::〜EException()
00000000000663b6 T EException :: operator = const&)
< ...>
000000000028de40 V用于EException的类型信息
000000000028dd80用于EException的V型信息*
000000000007342b V用于EException的类型信息名
0000000000072ab7 V 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 )
< ...>
E typeinfo for EException
问题可能是,
B 使用自己的
EException
的typeinfo,而C
使用A
?我将如何解决这个问题?
我的环境:
- gcc 4.6.3 on x86_64-linux-gnu
- 使用Qt
感谢您的帮助! p>
解决方案我有类似的问题gcc< 4.5,跨共享库边界使用RTTI符号,但不使用gcc 4.6。
如前所述,vtable(包含typeinfo对象的一个条目)用于
EException
似乎在一些翻译单元中是重复的,这肯定是gcc< 4.5(好吧,这是一个libsupc ++的问题,据我所知,不是合并type_info对象)。通过在中定义一个虚拟的out-of-line析构函数(它必须是标题中的第一个虚函数声明)来锚定
EException
/ code>
发布
EException
的完整头文件I know, this question has been asked quite some times, however I can't find a solution for my problem.
I have the following situation:
A / \ / \ B <-- C
- A is a shared library which contains the class
EException
- B and C link against A
- C is a shared library as well
- B dynamically loads C at runtime
At some point C throws an instance of
EException
:void doSometing() { throw EException("test-message"); }
in
B
I would like to catch this exception:try { doSomething(); } catch (const EException& ex) { // Not reached } catch (...) { // Not reached }
but as mentioned in the code, neither one of the catch clauses get called. Instead the thread, this code is executed in, gets aborted.
I tried the following things:
- The visibility attribute of
EException
is set to "default" when compiling A - The
EException
header file contains declarations only - I am using the linker option
-fvisibility=hidden
in A, B and C - I am using the linker option
-E
in C
Using
nm
I get forA
: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
for
B
:U EException::EException(QString const&) U EException::~EException() <...> 0000000000726f60 V typeinfo for EException
and for
C
:U EException::EException(QString const&) U EException::~EException() <...> U typeinfo for EException
Could the problem be, that
B
uses its own typeinfo ofEException
, whileC
uses the one provided byA
? How would I fix this?My environment:
- gcc 4.6.3 on x86_64-linux-gnu
- using Qt
Thank you for your help!
解决方案I had similar problems with gcc < 4.5 with RTTI symbols used across shared library boundaries, but not with gcc 4.6. However, you might still find the following information useful.
As already mentioned, the vtable (containing an entry to the typeinfo object) for
EException
seems to be duplicated in some translation units which was definitely a problem with gcc < 4.5 (well, it is an issue of libsupc++, as far as I know, not merging the type_info objects). Anchoring the vtable ofEException
by defining a virtual out-of-line destructor (it must be the first virtual function declaration in the header) inA
did the trick for me.Posting the complete header file for
EException
might also be helpful.这篇关于二元边界上的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!