捕获C++异常时触发SIGBUS错误的问题及编译器bug疑问
我遇到一个特殊情况:在C++中尝试捕获异常时触发了SIGBUS错误。预期代码会捕获std::invalid_argument异常并打印信息,但实际触发总线错误终止。更奇怪的是,不捕获异常时代码能正常抛出异常。
最小复现代码
#include <iostream> using Vertex = std::vector<double>; struct TestStruct { std::vector<Vertex> vertices; }; void testFunction(TestStruct& set1, TestStruct& set2) { if (set1.vertices.front().size() != set2.vertices.front().size()) { throw std::invalid_argument("set1 has different dimensions (" + std::to_string(set1.vertices.front().size()) + ") than set2 (" + std::to_string(set2.vertices.front().size()) + ")."); } } int main() { TestStruct set1; TestStruct set2; std::vector<Vertex> vertices1 = {{0.0, 0.0}}; std::vector<Vertex> vertices2 = {{0.0, 0.0, 0.0}}; set1.vertices = vertices1; set2.vertices = vertices2; try { testFunction(set1, set2); } catch (const std::invalid_argument& e) { std::cerr << "Exception: " << e.what() << std::endl; } }
错误现象
实际运行输出:
Process finished with exit code 138 (interrupted by signal 10:SIGBUS)
栈追踪信息
Process 7078 launched: '/Users/roland/Development/cps/sonia/build-debug/examples/cpp/Debug/sonia_exe' (arm64) Process 7078 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=261, address=0xdac11410) frame #0: 0x000000018d12aa58 libunwind.dylib`_Unwind_GetIP + 224 libunwind.dylib`: -> 0x18d12aa58 <+224>: autib x16, x0 0x18d12aa5c <+228>: mov x17, x16 0x18d12aa60 <+232>: xpaci x17 0x18d12aa64 <+236>: cmp x16, x17 Target 1: (sonia_exe) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=261, address=0xdac11410) * frame #0: 0x000000018d12aa58 libunwind.dylib`_Unwind_GetIP + 224 frame #1: 0x0000000180887c7c libc++abi.dylib`__gxx_personality_v0 + 588 frame #2: 0x0000000100494930 libunwind.1.dylib`unwind_phase2 + 388 frame #3: 0x0000000100494b68 libunwind.1.dylib`_Unwind_Resume + 100 frame #4: 0x0000000100005ad4 sonia_exe`testFunction(set1=0x000000016fdfef20, set2=0x000000016fdfef08) at sonia.cpp:21:9 frame #5: 0x00000001000061e8 sonia_exe`main at sonia.cpp:38:9 frame #6: 0x000000018054d0e0 dyld`start + 2360 (lldb)
后续测试
在干净环境中用不同编译器和架构测试后,仅在arm64架构的LLVM 18.1.8编译器中能复现该问题,其他环境均正常工作:
- arm64 LLVM 18.1.8:触发总线错误
输出:
栈追踪:zsh: bus error ./build_arm_llvm/example(lldb) run
Process 16227 launched: '/Users/roland/Development/personal/minimal_example/build_arm_llvm/example' (arm64)
Process 16227 stopped
- thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=261, address=0xdac11410)
frame #0: 0x000000018d12aa58 libunwind.dylib_Unwind_GetIP + 224 libunwind.dylib:
-> 0x18d12aa58 <+224>: autib x16, x0
0x18d12aa5c <+228>: mov x17, x16
0x18d12aa60 <+232>: xpaci x17
0x18d12aa64 <+236>: cmp x16, x17
Target 0: (example) stopped.
(lldb) bt - thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=261, address=0xdac11410)
- frame #0: 0x000000018d12aa58 libunwind.dylib
_Unwind_GetIP + 224 frame #1: 0x0000000180887c7c libc++abi.dylib__gxx_personality_v0 + 588
frame #2: 0x0000000100484930 libunwind.1.dylibunwind_phase2 + 388 frame #3: 0x0000000100484b68 libunwind.1.dylib_Unwind_Resume + 100
frame #4: 0x0000000100001ca4 exampletestFunction(TestStruct&, TestStruct&) + 544 frame #5: 0x0000000100001f80 examplemain + 416
frame #6: 0x000000018054d0e0 dyld`start + 2360
- frame #0: 0x000000018d12aa58 libunwind.dylib
- arm64 GCC 14.1.0:正常工作
输出:
terminate called after throwing an instance of 'std::invalid_argument'
what(): set1 has different dimensions (2) than set2 (3).
zsh: abort ./build_arm_g++/example
- **arm64 Apple Clang 15.0.0**:正常工作 输出:
Exception: set1 has different dimensions (2) than set2 (3).
- **x86 GCC 13.2.0**:正常工作 输出:
terminate called after throwing an instance of 'std::invalid_argument'
what(): set1 has different dimensions (2) than set2 (3).
zsh: abort ./build_x86_gcc/example
- **x86 Apple Clang 15.0.0**:正常工作 输出:
Exception: set1 has different dimensions (2) than set2 (3).
## 疑问 请问这是否是特定LLVM版本的编译器bug? --- 内容的提问来源于Stack Exchange,提问作者RolandSt

