#define panic(...) do { \
fprintf(stderr, "panic: %s:%u: %s:", \
__FILE__, __LINE__, __func__); \
fprintf(stderr, " " __VA_ARGS__); \
abort(); \
} while (0)
// They all works
// panic: panic.cpp:17: main:
();
panic// panic: panic.cpp:18: main: 233
("%d", 233);
panic// panic: panic.cpp:19: main: 233 != 332
("%d != %d", 233, 332); panic
也可以弄一个类似于assert
的crash_if
,不同的是这个crash_if
不受编译选项的影响:
#define crash_if(cond, ...) do { \
if (cond) { panic(__VA_ARGS__); } \
} while (0)
// panic: panic.cpp:20: main:
(233 != 332);
crash_if// panic: panic.cpp:21: main: 233 != 332
(233 != 332, "%d != %d", 233, 332); crash_if
也可以直接用rusty-cpp
里的rusty_panic
和rusty_assert
:
https://github.com/seekstar/rusty-cpp/blob/main/include/rusty/macro.h
¶ 失败经验:stacktrace
上面的都只是打印了出错点的信息,但是没有打印调用栈。其实可以使用boost打印调用栈:
#include <iostream>
#include <boost/stacktrace.hpp>
using namespace std;
int main() {
std::cout << boost::stacktrace::stacktrace();
return 0;
}
0# 0x0000560AE9E033AD in ./stacktrace
1# 0x00007FF75B754290 in /usr/lib/libc.so.6
2# __libc_start_main in /usr/lib/libc.so.6
3# 0x0000560AE9E03285 in ./stacktrace
可以看到只有文件,没有显示行号。
根据官方文档:https://www.boost.org/doc/libs/1_80_0/doc/html/stacktrace/configuration_and_build.html
我试了一下addr2line:
g++ -DBOOST_STACKTRACE_LINK -DBOOST_STACKTRACE_USE_ADDR2LINE -lboost_stacktrace_addr2line -ldl -no-pie -fno-pie -g stacktrace.cpp -o stacktrace
但是只是打印了部分函数,仍然没有行号:
0# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::basic_stacktrace() at /usr/include/boost/stacktrace/stacktrace.hpp:129
1# 0x00007FA7E2134290 in /usr/lib/libc.so.6
2# __libc_start_main in /usr/lib/libc.so.6
3# _start at /build/glibc/src/glibc/csu/../sysdeps/x86_64/start.S:117
而boost_stacktrace_backtrace
在我的ArchLinux上没有。。。
所以就放弃了。