无法看到引发异常的代码行

Unable to see the code line throwing an exception

本文关键字:异常 代码      更新时间:2023-10-16

当我使用具有优化级别o3g++编译代码,然后使用lldb进行调试直到发生崩溃时,没有代码行在回溯中引发异常。我不想使用-g标志,因为我的源代码不必在生产中可见。

让我们考虑一个简单的案例:

测试.cpp

int main() {
bool isOdd = std::rand() & 1;
if (isOdd) {
throw std::logic_error("An exception for the odd number was thrown!");
} else {
throw std::logic_error("An exception for the even number was thrown!");
}
}

然后我编译它

g++ -o3 -std=c++14 -o test.o test.cpp

并使用以下一组命令查看回溯跟踪:

lldb test.o
r
bt

但是回溯跟踪并没有真正的帮助,因为它不包含抛出异常的代码行或传递给logic_error的字符串消息("An exception for the odd number was thrown!""An exception for the even number was thrown!"(:

...
frame #7: 0x00007fff5011f26f libc++abi.dylib`__cxa_throw + 121
frame #8: 0x0000000100000e11 test.o`main + 113
frame #9: 0x00007fff5215d015 libdyld.dylib`start + 1
...

有没有办法在不使用任何外部库的情况下克服此限制?

我使用MacOSg++作为编译器,LLDB作为调试工具。

一种方法是使用可变参数模板函数来重新引发给定的异常。模板参数包括id参数和异常参数。id是唯一编号,将用于标识引发异常的代码行。参数用于创建和重新引发异常。因此,代码可能如下所示:

template<uint32_t id, class... Arguments>
void rethrow(Arguments&&... args) {
std::rethrow_exception(std::make_exception_ptr(std::logic_error(std::forward<Arguments>(args)...)));
}
int main() {
bool isOdd = std::rand() & 1;
if (isOdd) {
rethrow<1>("An exception for the odd numbers!");
} else {
rethrow<2>("An exception for the even numbers!");
}
} 

在我重新编译代码并检查回溯跟踪后,在我的情况下id = 1

frame #9: 0x0000000100000c65 test.o`void rethrow<1u, char const (&) [34]>(char const (&&&) [34]) + 69

因此,从

rethrow<1>("An exception for the odd numbers!");