c++ - 在 Mac OS X 上以多态方式捕获 -fno-rtti 共享库中的异常

标签 c++ macos gcc shared-libraries rtti

我正在使用 f-no-rtti 构建一个共享库。在内部,此库抛出 std:invalid_argument 并捕获 std::exception,但从未输入 catch 子句。

以下代码重现了该问题(g++ 4.2、Mac OS X 10.6):

// library.cpp: exports f(), compiled with -fno-rtti
#include <stdexcept>
#include <iostream>
extern "C" {
    void f() {
        try {
            throw std::invalid_argument("std::exception handler");
        } catch( std::exception& e) {
            std::cout << e.what() << "\n";
        } catch(...) {
            std::cout << "... handler\n";
        }
    }
}

// main.cpp: the main executable, dynamically loads the library
#include <dlfcn.h>
typedef void(*fPtr)();

int main() {
    void* handle = dlopen( "./libexception_problem.dylib", RTLD_LAZY );
    fPtr p_f = reinterpret_cast<fPtr>( dlsym( handle, "f" ) );
    p_f();
}

输出:

MacBook-Pro:teste pfranco$ # works fine with rtti
MacBook-Pro:teste pfranco$ g++ -c library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ main.cpp -o main && ./main
std::exception handler
MacBook-Pro:teste pfranco$ # breaks with -fno-rtti
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ #-no_dead_strip_inits_and_terms doesn't change anything
MacBook-Pro:teste pfranco$ g++ -c -no_dead_strip_inits_and_terms -fno-rtti library.cpp && g++ -no_dead_strip_inits_and_terms -shared -o libexception_problem.dylib library.o && g++ -fno-rtti -no_dead_strip_inits_and_terms main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ # linking against the shared library works, but this isn't always an option
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main -L. -lexception_problem && ./main
std::exception handler

只有当抛出的代码在共享库中,并且捕获的类型是实际异常的基类时才会发生这种情况 - catch (std::invalid_argument&) 工作正常,std::logic_error& 没有。

有趣的是,这不会发生在 Linux 上,即使运行完全相同的命令也是如此。

问题:

  1. 为什么会这样?这是错误、未定义的行为还是设计使然?
  2. 如果没有链接到库,我怎样才能让它工作?

非常感谢。

最佳答案

事实证明这是 Apple 的 gcc 上的错误。不过,他们最近回复了我的错误报告,表示不会修复。

关于c++ - 在 Mac OS X 上以多态方式捕获 -fno-rtti 共享库中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3638237/

相关文章:

c - lambda宏如何创建lambda?

c++ - 从 QFile 获取 QByteArray 并将其写入同一个文件

c++ - 在套接字编程中选择在 Windows 中挂起一段时间?

c++ - 将两个 C++ 函数转换为 Pascal

macos - 允许 AppleScript 脚本在未经许可的情况下运行

c - 忽略或重新定义 GCC 标准预定义宏

c++ - OpenGL 洪水填充无法识别边界

java - 如何在 Mac OS 中自定义 Java 应用程序的应用程序菜单

git - Mac - 从 Git 终端删除大于 '>'

c++ - eclipse mars c/c++ 不会在 Windows 7 上构建