使用 gdb 调试多线程代码但无法访问私有变量?

Posted

技术标签:

【中文标题】使用 gdb 调试多线程代码但无法访问私有变量?【英文标题】:Debugging multithreaded code with gdb but no access to private variables? 【发布时间】:2010-08-12 22:25:11 【问题描述】:

大家好。我的程序在几个部分使用 OpenMP 来执行多线程。它在大多数情况下都有效,但偶尔会停顿并坐在那里。所以我在调试器中运行它,我发现它停止的区域。然后我尝试检查当前变量,我得到了这个:

169      if(0<=myPtr[3] && myPtr[3]<=1)//Reassign the velocities.
(gdb) print myPtr[3]
No symbol "myPtr" in current context.

我不确定这是为什么。当它只是单线程时,我可以打印它。我私有化了那个变量,我想当我要求它打印一些东西时,程序不会知道我指的是哪个线程(即使这个http://cc.jct.ac.il/cc-res/online-doc/gdb/gdb_26.html#SEC26 说总会有一个当前线程......?)。所以,如果我选择一个线程,我会得到相同的东西:

(gdb) info threads
  3 process 32970 thread 0x4203  0x90f9846e in __semwait_signal ()
  2 process 32970 thread 0x3007  0x90f9846e in __semwait_signal ()
* 1 process 32970 local thread 0x2e03  mover3dsurfaces (.omp_data_i=0xbffff030) at mover3dsurfaces.cpp:174
(gdb) thread 1
[Switching to thread 1 (process 32970 local thread 0x2e03)]
mover3dsurfaces (.omp_data_i=0xbffff030) at mover3dsurfaces.cpp:174
174       partList.velocity(i,3) = velPtr[2];
(gdb) print velPtr[1]
No symbol "velPtr" in current context.

我实际上对这部分有点困惑。我的机器只有两个处理器。怎么会有3个线程?我看到 __semwait_signal() 之前的两个十六进制数字是相同的,但我不知道他们为什么要分开。如何查看单个线程的变量?

谢谢!

【问题讨论】:

【参考方案1】:

如果你还没有解决这个问题...

我遇到了同样的问题,并在使用 g++ 编译时使用 -gstabs+(而不仅仅是 -g)选项解决了它。

但是,在尝试打印共享变量时,我仍然得到“当前上下文中没有符号“var””。出于某种原因,打印也是全局变量的共享变量没有问题 (??)

【讨论】:

【参考方案2】:

我的机器只有两个处理器。 怎么会有3个线程?

线程数与(真实或虚拟(AKA 超线程)CPU 内核的数量无关。 您可以拥有(几乎)任意数量的线程(仅受操作系统限制)。操作系统的调度程序负责以公平的方式将 CPU 时间分配给线程 - 并唤醒休眠的线程,如果它们有新的东西(阻塞 I/O 完成,套接字上的新数据等)。

关于您的“未找到符号”问题:是否有完整的或只有有限的调试信息可用? (您使用了哪个 -g 选项?)以及哪个 gdb 版本? 可能会发生变量或指针可以“优化”并保存在寄存器中的情况。然后 gdb 无法显示变量的值。但是,我使用的所有 gdb 版本仍然知道该符号存在,但无法给出值(它显示一条消息“值已优化”)。

【讨论】:

版本:mayer:~ declan$ gdb -v GNU gdb 6.3.50-20050815(Apple 版本 gdb-966),我正在使用选项 -ggdb 进行编译。在一个测试程序中,我让它使用 OpenMP 循环并显示每次迭代所在的当前线程。它只产生了两个循环。在这里,我也没有指定要创建的线程数,那为什么会选择三个呢?另外,重申一下,当它不是多线程时,我可以做得很好。我可以打印任何我想要的变量。【参考方案3】:

我有时也注意到这一点。但我通常会通过 print *this 转储当前对象的内容来解决它(假设 velPtr 在当前对象中)。

我也想知道最终答案,但同时这种解决方法可能会对您有所帮助。

【讨论】:

谢谢。我实际上一直在使用它,它很有用。但是,这到底是怎么回事!

以上是关于使用 gdb 调试多线程代码但无法访问私有变量?的主要内容,如果未能解决你的问题,请参考以下文章

从实践到原理掌握 GDB

从实践到原理掌握 GDB

从实践到原理掌握 GDB

用gdb调试python多线程代码-记一次死锁的发现

如何使用GDB调试多线程

Linux C/C++代码 使用gdb进行coredump调试