无法捕获的C ++异常(共享库,arm-linux-gnueabi-g ++)

时间:2011-08-19 12:34:52

标签: exception gcc shared-libraries arm

我遇到了一个与跨越DSO边界的异常相关的奇怪问题。 当使用arm-none-linux-gnueabi-g ++为嵌入式linux板编译代码时,无法捕获异常,如果使用ubuntu中的普通gcc编译器进行编译,一切正常:(

澄清:

我们有三个组成部分:

一个可执行文件,它通过dlopen(),dlsym()加载DSO ..

一个DSO文件(libMod2.so),包含一个抛出自定义EException的类MOD2 (在调用throwException()

时从std :: runtime_error派生)

一个DSO文件(libtest.so),包含一个类MOD1,它获取一个指向MOD2类的指针并调用MOD2 :: throwException()。

void MOD1::setMod2(IMOD2* mod2){
    cout << "Calling mod2 throwException()"  << endl;
    try{
       mod2->throwException();
    }catch(EException& e){
       cout << "Got you!" << endl << e.what() << endl;
    }catch (...){
       cout << "slippery shit..."  << endl;
    }
}

现在的问题是,arm目标上的第一个异常处理程序无法捕获异常。

我认为链接时会产生问题: DSO上的nm -C在为EException进行grepping时显示出一些差异。

:定位:

toterhaa@develop-TT:/var/lib/tftpboot$ /opt/freescale/usr/local/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-none-linux-gnueabi-g++ --version
arm-none-linux-gnueabi-g++ (4.4.4_09.06.2010) 4.4.4
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOS



toterhaa@develop-TT:/var/lib/tftpboot$ nm -C libtest.so | grep EEx
00009ef0 V typeinfo for EException
000017f4 V typeinfo name for EException

Ubuntu的:

toterhaa@develop-TT:/nfs$ g++ --version
g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

toterhaa@develop-TT:/nfs$ nm -C libtest.so | grep EEx
0000303c d DW.ref._ZTI10EException
00002edc V typeinfo for EException
00001373 V typeinfo name for EException

使用ubuntu gcc创建的DSO还有一个符号DW.ref._ZTI10EException。我认为解决方案是将这个符号带入arm-DSO,但是如何?

有人知道这个问题吗?

1 个答案:

答案 0 :(得分:0)

问题解决了!

问题与链接器无关,它更简单,更简单。

我通过在dlopen()调用中添加RTLD_GLOBAL来解决它。似乎我的ubuntu安装中的标准gcc默认设置了这个,并且arm目标的编译器使用RTLD_LOCAL作为默认值。