【问题标题】:Clang with libc++ exceptions带有 libc++ 异常的 Clang
【发布时间】:2018-08-03 13:05:13
【问题描述】:

我一直在尝试不同的 c++ 库,并发现以下内容: 简单的应用:

#include <iostream>

int main(int argc, char* argv[])
{
    try
    {
        throw 1;
    }
    catch(...)
    {
        std::cout << "Exception is caught\n";
    }
}

当我像这样在 ARM 上编译它时:

clang++ -stdlib=stdlibc++

异常被按预期捕获。

但是当我把它改成:

clang++ -stdlib=libc++

我不断得到:

terminating with uncaught exception of type int
Aborted

我尝试使用各种标志显式打开异常,例如:

-fexceptions
-fcxx-exceptions
-frtti

但是这些标志都不起作用。未捕获异常的原因是什么? 会不会是因为安装不正确的libc++?

附: 在 PC 上,使用 libc++ 编译的同一程序按预期工作。 两个平台上的 libc++ 版本相同 - 3.7.0-1ubuntu0.1

【问题讨论】:

  • 如果是由于错误的 libc++ 安装造成的,您应该会遇到某种形式的链接器或加载器错误。我打赌 libc++ 只支持包罗万象的标准异常。
  • 那么为什么它可以在 PC 上运行?除了通常的 std::exception 也没有被捕获。
  • 也许 clang 会生成异常管理代码,假设它将与错误的展开库链接!?!??在两个生成的可执行文件上尝试 ldd。通常它与提供 _Unwind_x 符号的 GCC 版本的 libgcc_s 链接。也许还检查nm a.out | grep _Unwind。可能会出现有关预期符号版本的信息,例如 x86 上的“@@@GCC_3.0”。但我想知道链接阶段是如何成功的。

标签: c++ exception arm clang++ libc++


【解决方案1】:

是的,我在 PowerPC、ARM 甚至 X86 Linux 本身上遇到了完全相同的问题。 问题是(我用 PowerPC 跟踪它): throw 正在执行 __cxa_throw,它在 libc++ 的 libunwind 部分调用 _Unwind_RaiseException。这个 _Unwind_RaiseException 本身正在调用 unw_getcontext 以获取此时的所有寄存器。现在它尝试通过 ELF 文件中的“.eh_frame”向后查找调用函数。但是由于 UnwindLevel1.c 是一个 C 文件,因此在创建 .eh_frame 信息的装配部件中没有 .cfi_start ... 信息。意味着堆栈回溯直接在第一个函数 (_Unwind_RaiseException) 上结束,而不是进一步回溯以识别调用“catch”部分。 这可以通过使用 C++ 编译器(clang++ 而不是 clang)编译 libc++ 中的 .c 部分来纠正。在这种情况下,还会为函数生成 .cfi_start 信息。现在 Stack-Trace-Back 可以找到第一个函数以及直到 main 的先前函数(在我的测试用例中)。 对于 ARM,我现在正在寻找下一个问题,因为 Stack-Trace-Back 不起作用。它一遍又一遍地扫描相同的函数,但不会向后(无限循环)。

使用 clang++ 编译 .c 文件时,您会遇到 stdlib.h 中未定义部分的问题,因为它使用了来自 libcxx/include 而不是来自 MUSL 包含的错误 stdlib.h。我目前没有好的解决办法,只能手动修改一些头文件。

【讨论】:

  • 所有这些听起来像是一个应该报告给 libc++ 维护者的错误。
  • 我对 ARM 的无限循环的错误是,代码中没有添加“展开信息”。发生这种情况是因为我的目标未被检测为 EABI,因此编译器没有在汇编代码中创建 .save .setfp .pad 指令。
  • @Kei 您能否提供安装说明如何构建您的库?
【解决方案2】:

这是因为 libunwind 的编译中的一个错误。现已修复:https://reviews.llvm.org/D71117

使用 libc++ 和 libunwind 时,ARM 出现异常。 据我所知,它已在 LLVM-10.0.0 中修复。

【讨论】:

    猜你喜欢
    • 2020-06-05
    • 2012-09-14
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多