阅读前建议先了解:异常与错误处理、对象与资源管理。本篇介绍的新增能力属于 C++23。
source_location 能记录代码主动传入的调用点,但一次失败往往经过多个函数。传统方式依赖调试器或平台专属栈回溯接口;C++23 的 stacktrace 提供标准化的当前栈快照及查询接口。
它记录调用路径,不能代替业务错误类型、异常或日志上下文。先理解快照是可能不完整的诊断信息,再考虑把它附到错误记录。
#include <iostream>
#include <stacktrace>
std::stacktrace capture() { return std::stacktrace::current(); }
int main() {
const auto trace = capture();
for (const auto& entry : trace) {
static_cast<void>(entry.description());
}
std::cout << "capture complete\n";
}这个程序验证获取与遍历接口,输出故意不比较函数名、文件、地址或深度,因为它们依赖实现、优化、符号与部署方式。空快照也是允许结果;本例通过不代表生产环境已经提供有用符号。
实际诊断可把 std::to_string(trace) 保存到日志,也可逐项查看 description()、source_file() 和 source_line()。没有相关信息时字段可以为空或为零;不要把字符串格式视为可稳定解析的协议。
异常处理器中调用 current() 看到的是处理时的当前栈,抛出位置的栈可能已经展开。若要保存发生错误的位置,应在错误产生或抛出前明确捕获并附到错误对象;标准异常不会自动携带 stacktrace。
source_location 成本通常更小且位置由 API 传递,stacktrace 关注多层调用,两者互补。并不是每个正常返回都值得抓栈。
捕获与符号解析可能需要分配及平台支持,存在明显诊断开销。current() 的捕获接口有不抛保证,但资源不足可能得到空快照;描述转换、字符串生成等后续处理仍需按接口考虑异常与分配。
头文件和宏可用仍不保证链接环境已经完整。使用 libstdc++ 时,GCC 14 起需要链接 libstdc++exp.a(通常写作 -lstdc++exp);较早的 GCC 13 使用 libstdc++_libbacktrace.a。Clang 在 Linux 上也可能使用 libstdc++,所以不能只根据编译器名称决定链接参数。版本差异见 GCC 14 官方说明。
验证器先检查特性宏,再识别实际标准库。对 libstdc++,它通过编译器的 -print-file-name 查找上述支持库,并把已找到的库加在源码之后参与链接;其他标准库不添加 GNU 专用库。宏满足但支持库缺失、编译或链接失败,都会报告失败,不会计作跳过。
不能假定接口适合信号处理器或崩溃后任意状态下调用。线上栈信息可能包含路径和实现细节,输出策略应服从应用的日志边界;本教程不添加环境相关日志。
适合调试报告、错误采集和测试失败诊断。对协议错误仍使用明确错误码或 expected;对性能敏感路径可延迟或按需捕获。若目标库暂不支持,使用现有调试工具,不能将其他接口的 fallback 编译成功计作 stacktrace 通过。
从仓库根目录运行;源码就是本文的完整 cpp 围栏:
python3 tools/verify_examples.py --compiler clang++ --path docs/cpp23/stacktrace.md带 requires 元数据的示例按特性测试宏检查支持程度;缺少能力时报告跳过及原因,跳过不代表通过。使用真正的 GCC 时将 clang++ 替换为 g++。