Skip to content

std::stacktrace(C++23)

一句话

在任意位置抓取当前调用栈,拿到每个栈帧的函数名、源文件、行号——程序自省与崩溃诊断的标准工具,替代 backtrace 一类笨办法。

头文件

#include <stacktrace>

GCC 链接坑(实测)

GCC 的 <stacktrace> 符号不在主库里,要单独链接实验性库:GCC 16+ 是 -lstdc++exp(注意无下划线),GCC 12–15 是 -lstdc++_exp(有下划线)。CMake 里写 target_link_libraries(target PRIVATE stdc++exp)。漏链接会报 undefined reference to std::__stacktrace_impl::_S_current

核心 API 速查

操作签名说明
抓当前栈std::stacktrace::current()返回当前调用栈快照
带跳过帧stacktrace::current(skip, max_depth)跳过前 skip 帧、最多取 max_depth
栈深度st.size()帧数
取一帧st[i]拿到 stacktrace_entry
帧描述entry.description()函数名加地址等可读串
帧源位置entry.source_file() / source_line()源文件名与行号(需调试符号)
流输出std::cout << st直接打印整个栈

最小示例

cpp
// Standard: C++23
// 编译: g++ -std=c++23 demo.cpp -lstdc++exp     (GCC 16+)
#include <stacktrace>
#include <iostream>

void inner() {
    auto st = std::stacktrace::current();
    std::cout << "depth=" << st.size() << "\n";
    for (std::size_t i = 0; i < st.size(); ++i)
        std::cout << "  #" << i << " " << st[i] << "\n";
}
void outer() { inner(); }
int main() { outer(); }

实测输出(GCC 16.1.1,-std=c++23 -lstdc++exp):

text
depth=6
  #0  inner() [0x5ca9fa0aa28d]
  #1  outer() [0x5ca9fa0aa3d4]
  #2  main [0x5ca9fa0aa3e0]
  #3  <unknown> [0x7f1709227740]
  #4  __libc_start_main [0x7f1709227878]
  #5  _start [0x5ca9fa0aa184]

自己写的函数(inner/outer/main)名解析出来了;动态库部分显示 <unknown> 属正常,那几帧地址未符号化。

嵌入式适用性:低

  • 依赖符号表与运行时栈回溯,裸机和 RTOS 上通常不可用或需专门移植
  • 带符号信息会撑大镜像;-s strip 后只剩地址
  • 嵌入式更常用硬件断点、ITM、SEGGER RTT,或自定义 crashdump 回溯
  • host 端工具链、测试桩、CI 失败诊断倒是正好用得上

编译器支持

GCCClangMSVC
121619.34

另见


部分内容参考自 cppreference.com,采用 CC-BY-SA 4.0 许可

v0.10.0-6-gbcee94e · bcee94e · 2026-08-20