Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ GDB调试多线程,单线程执行不可预测_C++_Multithreading_Gdb - Fatal编程技术网

C++ 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,但这个变

我是GDB新手,不确定你们是否有过这样的经历:当我使用GDB调试一个有两个线程的程序时,我发现逐行执行不是线性的,或者即使对于一个线程也是不可预测的,并且打印出来的变量值也令人困惑。假设我有一个程序(在C++中)如下所示:

(我正在ubuntu命令行上调试,使用gdb的
-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  }
.....