用 info threads 可列出所有线程的 id、状态(running/stopped/blocked)、栈顶函数及源码位置;lwp 字段为真实 tid,用于查 /proc/pid/task/tid/stat 获取 utime/stime。

gdb里怎么列出所有线程及其状态
用 info threads 就能立刻看到当前所有线程的 ID、状态(running / stopped)、函数调用栈顶端和所在源码位置。它不显示 CPU 时间或运行时长,但这是后续分析的基础——没列全线程,后面查统计就无从谈起。
常见误区是只记住了 thread apply all bt,却忘了先确认线程是否真的都挂住了。比如某个线程正处在系统调用中(如 read() 或 pthread_cond_wait()),info threads 会标为 blocked,但它其实仍在内核态运行,不是“卡死”。
- 线程 ID 是 gdb 内部编号(如
1、2),不是 OS 的gettid()值;需要看输出里的LWP字段才是真实 tid - 如果某线程显示
?? ()且无符号信息,说明没加载对应 shared library 的 debug info,set solib-search-path或重新编译带-g -rdynamic可缓解 - 在 core dump 中执行
info threads时,所有线程都是 stopped 状态,无法反映运行时活跃度
如何获取每个线程的用户态/内核态 CPU 时间
gdb 本身不提供线程级 CPU 时间统计——它不是性能分析器。真正能拿到 utime 和 stime 的是 Linux 的 /proc/[pid]/task/[tid]/stat。你得先从 gdb 里拿到线程的真实 tid(即 info threads 输出中的 LWP),再手动查 procfs。
例如,某线程显示:2 Thread 0x7ffff7800700 (LWP 12345) 0x00007ffff7bcf54d in pthread_join (),那它的 tid 就是 12345,对应文件是 /proc/$(pidof your_program)/task/12345/stat。第 14 字段是 utime(jiffies),第 15 是 stime(jiffies),需除以 sysconf(_SC_CLK_TCK) 换算成秒。
- 不能依赖
thread apply all p $_类命令去读取寄存器或内存来估算时间——没有对应寄存器暴露运行时长 - 如果你在调试 live 进程,
cat /proc/[pid]/task/[tid]/stat必须在 gdb attach 同一进程的前提下执行,否则 pid 可能已变 - 注意:jiffies 是累计值,不是瞬时速率;两次采样差值才有意义
用 thread apply all + 自定义命令粗略判断线程活跃度
虽然 gdb 不内置“哪个线程跑得最多”的指标,但你可以用 thread apply all bt 1 快速扫一遍各线程当前执行点,结合业务逻辑判断哪些线程大概率处于 hot loop 或频繁唤醒状态。
比如看到多个线程都停在 std::condition_variable::wait(),说明它们大部分时间在休眠;而若好几个线程反复出现在 std::vector::push_back 或自定义的 process_message() 里,就值得怀疑是不是负载不均或锁竞争热点。
- 避免用
thread apply all bt查全栈——输出爆炸且掩盖关键模式;bt 1或bt 2足够定位入口函数 - 可配合
set print pretty off防止缩写干扰关键词搜索 - 如果线程刚被 signal 中断(如
SIGUSR1),栈顶可能是__libc_pause或nanosleep,不代表它“空闲”,只是恰好被截停
更靠谱的替代方案:别只靠 gdb 查线程统计
真要量化多线程行为,gdb 是错位工具。推荐组合使用:perf record -e sched:sched_switch -s --call-graph dwarf ./your_program 抓上下文切换,再用 perf report -g 看各线程调度热力;或者用 pidstat -t -p $(pidof your_program) 1 实时观察 %CPU per LWP。
gdb 的价值在于定格某一时刻的精确状态,而不是测量。强行用它做统计,就像用万用表测网络延迟——能读数,但结果既不准也不代表真实负载分布。
最容易被忽略的一点:线程 tid 在 fork() 后会重排,/proc/task/*/stat 中的字段顺序固定但含义依赖内核版本;Linux 5.10+ 新增了 proc/[pid]/task/[tid]/statm 和 status 里的 voluntary_ctxt_switches 字段,这些比硬解析 stat 更稳定。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











