Uncatchable C++ exceptions (Shared libs, arm-linux-gnueabi-g++)
我正面临一个与跨 DSO 边界引发的异常有关的奇怪问题。
当使用 arm-none-linux-gnueabi-g 为嵌入式 linux 板编译代码时,如果使用来自 ubuntu 的普通 gcc 编译器编译,则无法捕获异常,一切正常:(
澄清:
我们有三个组件:
一个可执行文件,通过 dlopen(), dlsym()..
加载 DSO
一个 DSO 文件 (libMod2.so),包含一个抛出自定义 EException 的类 MOD2
(源自 std::runtime_error)调用 throwException()
时
一个 DSO 文件 (libtest.so),包含一个类 MOD1,该类获得一个指向 MOD2 类的指针并调用 MOD2::throwException()。
1 2 3 4 5 6 7 8 9 10 | 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 上的
目标:
1 2 3 4 5 6 7 8 9 10 11 | 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:
1 2 3 4 5 6 7 8 9 10 | 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 有一个附加符号
有人知道这个问题吗?
问题解决了!
问题与链接器无关,它更简单,更简单。
我通过在 dlopen() 调用中添加 RTLD_GLOBAL 解决了这个问题。我的 ubuntu 安装中的标准 gcc 似乎默认设置了这个,并且 arm 目标的编译器默认使用 RTLD_LOCAL。