包含 try-catch 块的库是使用 动态加载dlopen
的,try-catch 块如下所示:
try {
throw "sth";
} catch (...) {}
动态加载库 abort 的程序抱怨:
在抛出 ... 的实例后
调用终止 递归调用终止
回溯是:
(gdb) bt
#0 0xb6c1904c in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:66
#1 0xb6c1c690 in __GI_abort () at abort.c:90
#2 0xb64ef634 in __gnu_cxx::__verbose_terminate_handler () at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/vterminate.cc:50
#3 0xb64ed4d8 in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_terminate.cc:38
#4 0xb64ed500 in std::terminate () at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_terminate.cc:48
#5 0xb64ed898 in __cxxabiv1::__cxa_rethrow () at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_throw.cc:122
#6 0xb64ef640 in __gnu_cxx::__verbose_terminate_handler () at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/vterminate.cc:80
#7 0xb64ed4d8 in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_terminate.cc:38
#8 0xb64ed500 in std::terminate () at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_terminate.cc:48
#9 0xb64ed83c in __cxxabiv1::__cxa_throw (obj=0x50ec50, tinfo=<optimized out>, dest=<optimized out>) at ../../../../../gcc~linaro-4.8-2013.12/libstdc++-v3/libsupc++/eh_throw.cc:84
#10 0xb52d105c in init () at xxx.cpp:287
#11 0xb6f628e4 in start_app (appname=0x19dc09 "xxx", app=0xb52f5b7c <xxx>) at app-core.c:605
#12 0xb6f63c60 in __app_install (appname=0x19dc09 "xxx", app=0xb52f5b7c <xxx>, library=0x19deb9 "libxxx.so", dlhandle=0x50e220) at app-core.c:1008
#13 0xb6f63efc in app_install_x (appname=0x19dc09 "xxx", library=0x19deb9 "libxxx.so") at app-core.c:1060
#14 0xb6f663ac in create (nn=0x19db40) at plugin-loader.c:55
#15 0xb6f624cc in start_stop_single_instance (appname=0xad60 "plugin", app=0x133b0 <app_plugin_loader>, start=1, nn=0x19db40) at app-core.c:513
#16 0xb6f6276c in start_stop_instances (appname=0xad60 "plugin", app=0x133b0 <app_plugin_loader>, start=1) at app-core.c:561
#17 0xb6f6294c in start_app (appname=0xad60 "plugin", app=0x133b0 <app_plugin_loader>) at app-core.c:615
#18 0xb6f63c60 in __app_install (appname=0xad60 "plugin", app=0x133b0 <app_plugin_loader>, library=0xb6fb2f7c "built-in", dlhandle=0xb6ffda60) at app-core.c:1008
#19 0xb6f63cfc in app_install (appname=0xad60 "plugin", app=0x133b0 <app_plugin_loader>) at app-core.c:1017
#20 0x0000a2e4 in main (argn=2, argv=0xbefffe54) at main.c:299
如果我编译并作为可执行程序运行,它会很好地工作。
有什么想法可以解决这个问题吗?
谢谢。
附言
编译器的版本是:
$ arm-hisiv400-linux-g++ --version
real-arm-hisiv400-linux-g++ (Hisilicon_v400) 4.8.3 20131202 (prerelease)
Copyright (C) 2013 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.
库的编译标志是:
-g -O2 -fPIC -DPIC -Wall -Wextra -Wno-unused-parameter
一个可重现的例子:
你好.cc
extern "C" {
void hello() {
try {
throw "hello world";
} catch (...) {}
}
}
编译:
arm-hisiv400-linux-g++ -c -g -O2 -Wall -Werror -fPIC hello.cc
arm-hisiv400-linux-g++ -fPIC -DPIC -shared libunwind-arm.so libunwind.so -g -O2 hello.o -Wl,-soname -Wl,hello.so -o hello.so
注意打包/链接的libunwind-arm.so
和libunwind.so
,我终于发现这是问题所在。
这两个库是由我的共享库所需的库引入的,删除它们后效果很好。
而main.c:
#include <dlfcn.h>
int main(int argc, char* argv[]) {
void* handle = dlopen(argv[1], RTLD_GLOBAL | RTLD_NOW);
if (handle == NULL)
return 1;
typedef void(*func)();
func f = (func)dlsym(handle, "hello");
if (f == NULL) {
return 1;
}
f();
return 0;
}
并编译 main.c:
arm-hisiv400-linux-gcc main.c -g -O2 -Wall -Werror -ldl -o hello