non-stop模式下默认仅暂停当前线程,其余线程继续执行;需用scheduler-locking on锁定调度或continue -a恢复所有线程,暂停其他线程须借助断点、SIGSTOP信号或条件断点。

non-stop 模式下默认不会暂停其他线程
如果你发现 continue、next 或 step 后只有当前线程停了,其余线程还在跑——这恰恰是 non-stop 模式的行为特征,不是 bug。它本意就是「单线程控制」:当前线程暂停时,别的线程照常执行。所以,想让其他线程也暂停,不能靠默认行为,得主动干预。
用 scheduler-locking on 锁定调度
这是最直接有效的办法。启用后,只要你在调试当前线程(比如执行 step 或 next),GDB 就会阻止其他线程抢占 CPU 时间片,相当于把它们“冻结”在当前状态。
-
set scheduler-locking on:启用锁定,步进时其他线程不运行 -
set scheduler-locking step:更精细的控制——仅在单步(step/next)时锁住其他线程;但continue时它们仍可自由运行 -
set scheduler-locking off:完全放开调度,所有线程随时可能被调度执行
注意:scheduler-locking 和 non-stop 可共存。即使 non-stop on,只要 scheduler-locking on,步进时其他线程也不会动。
想让所有线程一起继续?用 continue -a
在 non-stop 模式下,continue 默认只恢复当前线程。如果你已手动暂停了多个线程(比如用 signal SIGSTOP 或断点触发),又想一并唤醒全部,就得显式加 -a 参数:
-
c -a或continue -a:恢复所有线程 -
thread apply all continue:等效命令,语义更明确
但反过来,它不能“暂停”其他线程——这只是恢复手段,不是暂停开关。
真正暂停指定线程?靠信号或断点
GDB 本身没有“暂停线程 X”的直接命令,但可通过间接方式达成:
- 对目标线程设断点:
thread 2切到线程 2,再break some_func,它下次执行到该函数就会停 - 发信号让它自己挂起:
signal SIGSTOP(需先thread N切过去);但注意:SIGSTOP 不会被程序捕获,GDB 会接管并使该线程进入 stopped 状态 - 利用条件断点卡住:
break file.c:100 if thread_id == 3,只对特定线程生效
关键点在于:GDB 的线程暂停本质是“等待事件触发”,不是操作系统级的 suspend。你得给它一个能命中且可控的停止点。
容易忽略的是:non-stop on + scheduler-locking off 组合下,step 过程中其他线程可能悄悄改掉共享变量,而你完全没感知——这种竞态恰恰是多线程 bug 的温床。真要稳住现场,别只依赖模式切换,得配合断点位置、条件约束和线程切换意识。











