C++ GDB调试多线程,单线程执行不可预测
我是GDB新手,不确定你们是否有过这样的经历:当我使用GDB调试一个有两个线程的程序时,我发现逐行执行不是线性的,或者即使对于一个线程也是不可预测的,并且打印出来的变量值也令人困惑。假设我有一个程序(在C++中)如下所示: (我正在ubuntu命令行上调试,使用gdb的C++ GDB调试多线程,单线程执行不可预测,c++,multithreading,gdb,C++,Multithreading,Gdb,我是GDB新手,不确定你们是否有过这样的经历:当我使用GDB调试一个有两个线程的程序时,我发现逐行执行不是线性的,或者即使对于一个线程也是不可预测的,并且打印出来的变量值也令人困惑。假设我有一个程序(在C++中)如下所示: (我正在ubuntu命令行上调试,使用gdb的-tui模式) 。。。。。 70表示(int i=0;idoCalc(); 74 int v2=条->获取(foo); 75 } ..... 开始时,程序在第72行停止,然后我逐行走到第74行。此时,我打印出了值v1,但这个变
-tui
模式)
。。。。。
70表示(int i=0;idoCalc();
74 int v2=条->获取(foo);
75 }
.....
开始时,程序在
第72行停止,然后我逐行走到第74行。此时,我打印出了值v1
,但这个变量似乎还没有有意义的值。然后,如果我键入“下一步”,程序执行将再次跳回到第72行!!这是引起我困惑的第一件事。然后我继续步骤到下一行,直到它到达第74行。此时,我打印出了v1
,这一次它有一些有意义的价值。我仔细检查了迭代器I
,它的值是相同的,这意味着它在同一个循环的第I次执行中。我很困惑,这怎么会发生?谁能帮帮我吗?谢谢大家! 您描述的症状与调试优化代码时的预期相符。确保编译时不使用-O2
或类似标志,或在编译命令末尾添加-O0
多线程不太可能与您的问题有任何关系(尽管在单步执行时它确实会带来自己的挑战)。如果多线程正在影响您的调试,那么当执行从一个线程切换到另一个线程时,您应该在GDB中看到消息,例如[切换到线程0x7ffff61ec700(LWP 21427)]
。您已经关闭了所有编译器优化,是吗?调试多线程应用程序时,通常最好在下一行连续设置断点,而不是尝试单步执行。单步执行通常会导致“下一步”移动到不相关的代码,因为您所遵循的代码会进行系统调用。当然,如果您有多个线程运行相同的代码,这就更令人困惑了——一个单步命令有时会使代码看起来像是在向后运行:)这似乎与多个线程无关,而且都与编译器优化有关。首先,foo实际上不需要是一个变量<代码>i
可以完全优化(或者由于展开,只能在每次迭代中更新)。变量分配不需要有序v1
和v2
实际上根本不需要存在或分配!谢谢。这是因为代码在编译时经过了优化。我使用CMake
生成Makefile。我对编译器使用了RelWithDebInfo
标志,根据我的发现,这意味着:ompiler标志用于编译带有C源代码调试标志的发布版本。所以我想它还是或多或少地优化了执行。然后我将标志更改为-DCMAKE\u BUILD\u TYPE=Debug
,它现在就像一个符咒。
.....
70 for (int i = 0; i < MAX; i++) {
71 int foo = 1;
b+ 72 Bar *bar = f1();
73 int v1 = bar->doCalc();
74 int v2 = bar->get(foo);
75 }
.....