C++异常在clang 17.0.3上未被捕获。

10
这是我今天遇到的一个bug的简化版本。
#include <iostream>
#include <vector>
#include <stdexcept>

void run() {
    std::vector<int> v;
    throw std::runtime_error("error");
}

int main() {
    try {
        run();
    } catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}

我在 M1 Mac 上使用 Homebrew clang 版本 17.0.3 编译并运行了这段代码。
clang++ -std=c++20 -o main main.cpp

异常未被捕获,程序退出并显示如下信息:
Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)

如果我从run函数中删除std::vector<int> v;,或者在Linux上编译它,那么它就可以工作。
编辑: 所以,我最初是通过CLion使用cmake进行编译的,它还添加了-L/opt/homebrew/opt/llvm/lib
我手动测试了它的编译,结果是:
# works
clang++ -std=c++20 -o main main.cpp

# crashes with c++11, c++17 and c++20
clang++ -std=c++20 -O0 -o main -L/opt/homebrew/opt/llvm/lib main.cpp

# works
clang++ -std=c++20 -O1 -o main -L/opt/homebrew/opt/llvm/lib main.cpp

生成的汇编文件:https://drive.google.com/drive/folders/13UKnC0mp6_3l_QULO62ts_UQHK1ZR23u?usp=share_link 我猜-O1只是简单地去除了创建向量的操作,因为添加更多的代码来确保它被保留会导致陷阱。
在run()函数内创建一个空类,该类具有打印某些内容的析构函数,也会导致同样的问题。

2
你使用哪些编译器标志?你尝试过一些不同的标志,比如-std=xxx,其中xxx可以是c++11、c++14、c++17、c++20等,或者不同的优化级别吗?[编辑]将问题修改并将所有细节放入问题中。 - undefined
1
如果你添加了catch (...),那么这个块会捕获异常吗? - undefined
1
请问您能分享一下您的编译器生成的汇编代码吗?这看起来像是一个编译器的错误(为了消除您可能有的任何疑虑)。如果在使用“-O2”参数后行为没有改变,请提供两个汇编代码。 - undefined
1
@Balázsg 你试过一些不同的标志,比如-std=c++-17等吗?还有不同的优化级别,比如-O0-O1-O2-O3?请编辑问题并将所有信息放入其中。 - undefined
1
令人惊讶的是,-O1版本可以工作,但-O0版本却不能。你能否按照之前的要求,发布一个可以工作的版本和一个不能工作的版本的生成汇编代码?但无论如何,这更像是与-L/opt/homebrew/opt/llvm/lib选项有关的问题。 - undefined
显示剩余2条评论
1个回答

4
这是一个配置错误。来自于brew info llvm的摘录。
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
  LDFLAGS="-L/opt/homebrew/opt/llvm/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm/lib/c++"

llvm is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have llvm first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc

For compilers to find llvm you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"

使用-L/opt/homebrew/opt/llvm/lib/c++,代码按预期运行。

当我尝试使用llvm和异常处理进行编译时,我遇到了同样的问题。我还检查了brew info llvm,并按照说明进行操作(与您在这里的指示一致),但似乎并没有解决我的问题...使用-O1选项也可以使代码正确运行。 - undefined
@Sebastian 你确定编译器不会在-O1优化级别下移除导致问题的代码吗?在我的测试中似乎是这样的情况。 - undefined
抱歉如果我表达不清楚。我相信使用-O1确实使代码正确运行,但对我来说并不是一个可接受的解决方案。我从更新的clang / LLVM版本切换回了苹果XCode附带的版本,并放弃了一些不再支持的C++20特性,此后一切都恢复正常了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接