This is a simplified version of a bug that I ran into today.
#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;
}
I compiled and ran this code with Homebrew clang version 17.0.3 on an M1 Mac:
clang++ -std=c++20 -o main main.cpp
The exception is not caught and the program exits with:
Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)
If I remove std::vector<int> v;
from the run function or compile it on Linux, then it works.
Edit:
So, I was originally compiling through CLion using cmake which also added -L/opt/homebrew/opt/llvm/lib
.
I tested it compiling manually, results:
# 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
My guess is that -O1 simply stripped away creating the vector, because adding more code to make sure it's kept causes a trap.
Creating an empty class inside run()
, that has a destructor that prints something also causes this same problem.
It was a misconfiguration error.
Excerpt from 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"
Using -L/opt/homebrew/opt/llvm/lib/c++
the code runs as expected.