首页 > 解决方案 > 是否可以让 GDB 只运行一个线程

问题描述

我正在学习如何使用 GDB 调试多线程 C++11 程序。

这是我的测试代码:

void func()
{
    int i = 0;
    while (true) {
        std::cout << std::this_thread::get_id() << ": " << (i++) <<std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

int main()
{
    std::thread t1(func);
    std::thread t2(func);
    t1.join();
    t2.join();

    return 0;
}

嗯,这很简单:两个无限循环,每个循环都由一个线程执行。

我执行g++ -std=c++11 test.cpp -g -lpthread并得到一个二进制文件a.out

在终端 A 上运行后a.out,我打开另一个终端 B 并使用gdb:连接它gdb -p <PID_of_a.out>

现在a.out终端 A 上的输出按预期停止。

然后,我info thread在终端 B 上执行:

(gdb) info threads
  Id   Target Id         Frame
* 1    Thread 0x7f3b10c24740 (LWP 62395) "a.out" 0x00007f3b10803d2d in __GI___pthread_timedjoin_ex (threadid=139891642771200, thread_return=0x0, abstime=0x0,
    block=<optimized out>) at pthread_join_common.c:89
  2    Thread 0x7f3b0faca700 (LWP 62396) "a.out" 0x00007f3b1080cc70 in __GI___nanosleep (requested_time=0x7f3b0fac9d90, remaining=0x7f3b0fac9d90)
    at ../sysdeps/unix/sysv/linux/nanosleep.c:28
  3    Thread 0x7f3b0f2c9700 (LWP 62397) "a.out" 0x00007f3b1080cc70 in __GI___nanosleep (requested_time=0x7f3b0f2c8d90, remaining=0x7f3b0f2c8d90)
    at ../sysdeps/unix/sysv/linux/nanosleep.c:28

所以线程 1 是 main 函数,线程 2 和线程 3 是func.

然后我执行thread 2切换到线程2。

现在,我继续输入n以使线程 2 运行。

我想要做的是让线程 2 运行,同时让线程 3 继续停止。但是,由于在线程 2 上键入,似乎线程 3 也被执行n。这是终端 A 的输出:

139891642771200: 17
139891634378496: 17
139891642771200: 18
139891634378496: 18
139891642771200: 19
139891634378496: 19
139891634378496: 20
139891634378496: 21
139891634378496: 22
139891634378496: 23
139891642771200: 20
139891634378496: 24
139891634378496: 25

你可以看到最后第三行:139891642771200: 20,它来自线程 3。

所以我的问题是是否可以让 GDB 只运行一个线程?如果可能,我能做什么?

标签: c++multithreadingc++11gdb

解决方案


对于单步执行程序 ( step, next),GDB 支持将调度程序锁定到当前线程:

set scheduler-locking step

当然,只有当线程能够取得进展(即其他线程没有持有锁等)时,这样的单步才会起作用。

据我所知,运行程序(run, continue, finish)不存在这种可能性。


推荐阅读