c++ - 是否可以让 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 只运行一个线程?如果可能,我能做什么?
解决方案
对于单步执行程序 ( step
, next
),GDB 支持将调度程序锁定到当前线程:
set scheduler-locking step
当然,只有当线程能够取得进展(即其他线程没有持有锁等)时,这样的单步才会起作用。
据我所知,运行程序(run
, continue
, finish
)不存在这种可能性。
推荐阅读
- java - 使用java在数组中添加带参数的元素
- primefaces - 如何在 ap:confirmDialog 中设置 defaultCommand
- jquery - Jquery 步骤重新加载当前异步页面
- git - Git 在将分支与 master 合并时未检测到差异
- oracle - 更改oracle 12c数据库中的字符集
- javascript - 在 URL 中使用锚点或数据过滤器
- elasticsearch - 如何使用 NEST 在 Elastic 中指定每个字段实例的分析器
- laravel - 如何在 laravel 应用程序中使用不同的控制器方法
- java - 改造路径编码除了字符?
- csv - Jmeter从csv文件中删除重复行