All-Stop模式:
调试多线程程序时,如果某个线程断在一个断点上,调试器会让整个程序freeze,直到continue这个线程,程序中的其他线程才会继续运行。
这个限制使得被调试的程序不能够像真实环境中那样运行–当某个线程断在一个断点上,让其他线程并行运行。
Non-Stop模式:
当一个或多个线程停在断点上,其他线程仍会继续运行
Non-Stop模式的优势:
- 当其他线程停在断点上,有定时器的线程可以正常地运行,从而避免了不必要的超时;
- 当其他线程停在断点上,有watchdog的线程可以正常地运行,从而避免嵌入式硬件以为系统崩溃而重启
- 可以控制多个线程运行的顺序,从而重现 deadlock 场景。由于GDB可以用python脚本驱动调试,理论上可以对程序在不同的线程运行顺序下进行自动化测试。
在2009年下半年之后发布的Linux版本里都带有GDBv7.0之后的版本。
操作:
- 将以下3行添加到 ~/.gdbinit 以默认打开non-stop模式; 或者进入gdb后手动输入也一样。
set target-async 1
set pagination off
set non-stop on
-
attach 到正在运行的进程
-
下断点到某个线程
b file:line thr <thread_id>
thread_id 可以在gdb中用 info thr 命令查看
当这个线程执行到断点时,这个线程就停止了,但是其他线程不停止,还在继续执行
- 指定线程继续运行
thr apply <id1> <id2> <id3> continue
以下是示例程序,可以做以上的试验:
#include <thread>
#include <mutex>
#include <iostream>
#include <unistd.h>
void func()
{
while (1) {
std::cout << "In thread " << std::this_thread::get_id() << "......\n";
sleep(3);
}
}
int main()
{
std::cout << __func__ << '\n';
std::thread t1(func);
std::thread t2(func);
std::thread t3(func);
t1.join();
t2.join();
t3.join();
return 0;
}
(完)