二元边界上的异常 [英] Exceptions across binary boundary

查看:92
本文介绍了二元边界上的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,这个问题已经被问了很多次,但我找不到我的问题的解决方案。



我有以下情况: 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 for 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
    

    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 of EException, while C uses the one provided by A? 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 of EException by defining a virtual out-of-line destructor (it must be the first virtual function declaration in the header) in A did the trick for me.

    Posting the complete header file for EException might also be helpful.

    这篇关于二元边界上的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆