homebrew-core icon indicating copy to clipboard operation
homebrew-core copied to clipboard

Can't catch some exceptions in software built with LLVM >= 18.1.0

Open ngladitz opened this issue 1 week ago • 0 comments

brew gist-logs <formula> link OR brew config AND brew doctor output

~ brew config
HOMEBREW_VERSION: 4.3.7-47-g09223c7
ORIGIN: https://github.com/Homebrew/brew
HEAD: 09223c700a35c020f9922b36dce4cf045674467f
Last commit: 11 hours ago
Core tap HEAD: a143117c7186a880a00236e9cf04a3bcb45e4c11
Core tap last commit: 2 hours ago
Core tap JSON: 30 Jun 10:36 UTC
Core cask tap JSON: 30 Jun 10:36 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 8
HOMEBREW_SORBET_RUNTIME: set
Homebrew Ruby: 3.3.3 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/bin/ruby
CPU: octa-core 64-bit arm_blizzard_avalanche
Clang: 15.0.0 build 1500
Git: 2.45.2 => /opt/homebrew/bin/git
Curl: 8.6.0 => /usr/bin/curl
macOS: 14.5-arm64
CLT: 15.3.0.0.1.1708646388
Xcode: 15.4
Rosetta 2: false

~ brew doctor
Your system is ready to brew.

Verification

  • [X] My brew doctor output says Your system is ready to brew. and am still able to reproduce my issue.
  • [X] I ran brew update and am still able to reproduce my issue.
  • [X] I have resolved all warnings from brew doctor and that did not fix my problem.
  • [X] I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.

What were you trying to do (and why)?

I was trying to build and run software that uses C++ exceptions (because I want to).

What happened (include all command output)?

Some C++ exceptions can not be caught resulting in abort() / process termination.

A reduced testcase of something that produces the same issue (save as e.g. test.cpp):

#include <stdexcept>
#include <iostream>
class c : public std::runtime_error {
public:
  c(std::string a) : runtime_error(a) {}
};
class d {
public:
  d();
};
class e {
public:
  e();
};
d::d() { throw c(""); }
void f() { d(); }
e::e() {
  try {
    f();
  } catch (std::exception) {
    std::cout << "Caught exception" << std::endl;
  }
}
int main() { e b; }

Based on a test case that was provided in this LLVM upstream issue: https://github.com/llvm/llvm-project/issues/92121

With LLVM 18 installed via homebrew this unexpectedly gives:

/opt/homebrew/opt/llvm/bin/clang++ test.cpp -o test -L/opt/homebrew/opt/llvm/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm/lib/c++ 
./test
libc++abi: terminating due to uncaught exception of type c: 
[1]    99514 abort      ./test

With Apple Clang 15 this expectedly gives:

clang++ test.cpp -o test                                                                           
./test
Caught exception

Note my comment on the upstream issue: https://github.com/llvm/llvm-project/issues/92121#issuecomment-2198511835

The issue seems to go away when configuring LLVM with: -DLIBCXXABI_USE_LLVM_UNWINDER=OFF -DCOMPILER_RT_USE_LLVM_UNWINDER=OFF.

The commit message in the regressing commit seem to suggest that vendors may want to do this (which in this case I guess might mean homebrew?). It would fix my issue but I am uncertain what other implications it would have.

What did you expect to happen?

I expect to be able to catch C++ exceptions.

Step-by-step reproduction instructions (by running brew commands)

brew install llvm

After that compile and run the test case as outlined above.

ngladitz avatar Jun 30 '24 11:06 ngladitz