无法捕捉的 C++异常(共享库、arm-linux-gnueabi-g++)
我面临着一个与跨 DSO 边界抛出的异常相关的奇怪问题。 当使用arm-none-linux-gnueabi-g++为嵌入式linux板编译代码时,无法捕获异常,如果使用ubuntu中的普通gcc编译器编译,一切正常:(
澄清一下:
我们有三个组件:
一可执行文件,通过 dlopen()、dlsym() 加载 DSO。
一个 DSO 文件 (libMod2.so),包含一个 MOD2 类,该类会抛出自定义的 EException (派生自 std::runtime_error)当调用 throwException() 时,
一个 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;
}
}
现在的问题是,手臂目标上的第一个异常处理程序无法捕获异常。
我认为问题是在链接时产生的: DSO 上的 nm -C 在 grep 查找 EException 时显示出一些差异。
目标:
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,但是如何呢?
有人知道这个问题吗?
I'm facing a strange problem related to exceptions thrown across DSO boundaries.
When the code is compiled for embedded linux board with arm-none-linux-gnueabi-g++, the exceptions can't be caught, if compiled with normal gcc compiler from ubuntu everything works fine :(
To clarify:
We have three components:
one Executeable file, which loads DSOs via dlopen(), dlsym()..
one DSO file (libMod2.so), containing a class MOD2 which throws self defined EException
(derived from std::runtime_error) when calling throwException()
one DSO file (libtest.so), containing a class MOD1 which get's a pointer to class MOD2 located and calls 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;
}
}
The problem is now that the Exception couldn't be caught by the first exception handler on arm target.
I think the problem is produced when linking:
A nm -C
on the DSO show some differences when grepping for EException.
TARGET:
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
The DSO created with ubuntu gcc has a additional symbol DW.ref._ZTI10EException
. I think the solution is to bring this symbol also into the arm-DSO, but how?
Does anybody know this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题解决了!
问题与链接器无关,它更简单,更简单。
我通过将 RTLD_GLOBAL 添加到 dlopen() 调用来解决这个问题。看来我的 ubuntu 安装中的标准 gcc 默认设置了此设置,而 arm 目标的编译器默认使用 RTLD_LOCAL 。
Problem solved!
The problem is not linker related, it was simpler, much simpler.
I solved it by adding RTLD_GLOBAL to the dlopen() call. It seems that the standard gcc in my ubuntu installation sets this by default and the compiler for the arm target uses RTLD_LOCAL as default.