1

包含 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.solibunwind.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
4

0 回答 0