thread apply all bt是GDB中一次性查看所有线程调用栈的核心命令,用于快速定位卡死、死锁或崩溃问题;必须含apply关键字,可加full显示局部变量、quiet跳过无栈线程,配合--batch模式支持非交互式批量分析。

thread apply all bt 是最直接的命令
想快速看全所有线程当前执行到哪,不用逐个切换、手动 bt,就用这一条:thread apply all bt。它会依次对每个线程执行 backtrace,输出全部栈帧,是现场诊断卡死、死锁、崩溃的第一步。
常见错误现象:只输 bt,结果只看到主线程栈;或者输错成 thread all bt(语法错误,GDB 报 Undefined command)。
- 必须带
apply——thread apply all bt才合法 - 加
full可显示局部变量和寄存器:thread apply all bt full(调试符号完整时才有效) - 加
quiet可跳过无栈线程(如刚创建未调度的 pthread):thread apply all bt quiet
非交互模式下批量导出到文件
程序已卡死但不能进交互式 GDB?或者要写入日志做后续分析?用 --batch 模式:
gdb -q --batch --ex "set height 0" --ex "thread apply all bt full" ./myapp <code>core
或附着到运行中进程:gdb -q --batch --ex "set height 0" --ex "thread apply all bt full" -p <code>12345
关键参数含义:
-
-q:不打印 GDB 版本和版权信息,避免干扰解析 -
--batch:不进入交互,执行完即退出 -
set height 0:禁用分页,否则输出可能被截断 - 顺序很重要:
--ex必须在目标文件/进程 ID 之后,否则 GDB 会报错
info threads 后再针对性 bt,比盲目全打更高效
当线程数上百时,thread apply all bt 输出可能过长、难定位重点。先用 info threads 快速筛出可疑线程:
重点关注状态为 Blocked 或栈顶含 pthread_mutex_lock、__lll_lock_wait、std::mutex::lock 的线程。
- 执行
info threads,记下编号(比如线程 3、7、12) - 只对这几个线程查栈:
thread apply 3 7 12 bt - 若需看某一线程的锁地址,切过去后用
frame跳到pthread_mutex_lock那一层,再info registers查%rdi(x86_64)或x0(aarch64)——那通常是 mutex 地址
注意调试符号和编译选项的影响
没有调试符号,bt 只能显示函数地址(如 0x7f8a12345678),无法映射到源码行或变量名,排查效率断崖下降。
确保可执行文件或 core 文件是用以下任一方式编译的:
-
gcc -g2(默认级别,含行号和局部变量) -
gcc -ggdb3(GDB 专用,含宏定义,适合深度分析) - 避免仅用
-g1:它不记录行号,list和源码上下文全失效 - strip 过的二进制无法恢复符号——别在发布前 strip,保留
.debug段或单独存档调试文件
真正卡住时,你不会想对着一堆 ?? () 和地址猜逻辑。符号是否完整,往往决定一次 thread apply all bt 是救命稻草,还是废纸一张。



















