【问题标题】:How to catch exception thrown from library in GCC C++?如何在 GCC C++ 中捕获从库中抛出的异常?
【发布时间】:2010-12-16 23:22:59
【问题描述】:

当我使用 dlopen 动态加载库时,我似乎无法捕获该库引发的异常。据我了解,这是因为 dlopen 是一个 C 函数。

是否有另一种动态加载库的方法,可以捕获 GCC 中的库引发的异常?

在 Windows 中,您可以使用 LoadLibrary,但对于 Linux,我只找到 dlopen,但在使用 dlopen 时,我无法捕获异常。

编辑: 我试过 void* handle = dlopen("myLib.so", RTLD_NOW | RTLD_GLOBAL);我仍然无法捕获 myLib.so 引发的异常

编辑 2: 我用自己的命名空间抛出自定义异常。我希望能够在库之外捕获这些异常。 我希望能够在不同的编译器上编译,例如 GCC 3.2 和 GCC 4.1。

在 myLib2.so 我抛出异常,一个例子:

namespace MyNamespace {  
    void MyClass::function1() throw(Exception1) {  
        throw Exception1("Error message");  
    } 
}

在 myLib1.so 我想捕捉那个异常:

std::auto_ptr <MyNamespace::MyClass> obj = MyNamespace::getClass();
try {  
    obj->function1();  
} catch (MyNamespace::Exception1& e) {  
    std::cout << e.what();  //This is not caught for some reason.  
}

mylib1.so 动态加载 myLib2.so:

void* handle = dlopen("myLib2.so", RTLDNOW | RTLDGLOBAL);

适用于 Windows(捕捉我的异常),但我当然不使用 dlopen。

编辑 3:myLib1.so 是动态链接的。

【问题讨论】:

  • 也许有不同的编译设置。你能用objdump -TC mylib2.so | grep Exception1检查objdump -TC mylib1.so | grep Exception1的结果吗? typeinfos 的大小应该相等
  • objdump -TC mylib1.so | grep Exception1 在 objdump -TC mylib2.so 时什么也没给出grep Exception1 给出了一些。
  • 这很奇怪,可能是这个问题的根源。也许您有一些链接器选项阻止符号在 mylib1 中全局导出?
  • 我构建 mylib1 的标志是:-shared -fPIC -rdynamic -W1,--export-dynamic -W1,-soname,libMyLib.so 我构建 mylib2 的标志是一样的
  • 会不会是 mylib1 中的代码没有被执行?您看到什么行为,因为未捕获异常而调用 std::terminate?

标签: c++ gcc dynamic exception-handling


【解决方案1】:

您需要为 dlopen 指定 RTLD_GLOBAL 标志。这将允许正确的弱符号绑定,因此异常对象的每个 typeinfo 符号将指向同一个位置,这是异常处理 ABI 代码所需要的。

【讨论】:

  • 当我使用标志 RTLD_GLOBAL 进行 dlopen 时,我得到 dlerror: invalid mode for dlopen(): Invalid argument。无效*句柄 = dlopen("myLib.so", RTLD_GLOBAL);此 dlopen 语句位于我的代码调用的共享库中。我的代码 -> 共享库 -> 使用 dlopen("myLib.so", RTLD_GLOBAL); 动态加载另一个库
  • 我现在使用:void* handle = dlopen("myLib.so", RTLD_NOW | RTLD_GLOBAL);它确实可以编译,但我仍然无法捕获 myLib.so 引发的异常
  • 你抛出哪种类型的异常?你定制的?也许您可以使用简短的示例代码更新问题?以及系统和编译器的版本
【解决方案2】:

这取决于您使用的 GCC 版本。
首先,确保使用“-fPIC”编译所有内容并使用“-rdynamic”标志链接。
仍然需要 RTLD_NOW 标志。

【讨论】:

  • 我使用 -shared -fPIC -W1、--export-dynamic -W1、-soname、libTest.so 编译所有内容,但我完全不确定这些标志。我添加了 -rdynamic 并进行了测试,但我仍然无法捕获异常:-shared -fPIC -W1、-rdynamic --export-dynamic -W1、-soname、libTest.so
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 2011-11-11
  • 2014-05-04
  • 2010-11-26
  • 2019-09-18
  • 1970-01-01
  • 2012-08-11
相关资源
最近更新 更多