如何使用GDB调试多线程?

时间:2017-08-17 16:17:37

标签: debugging gdb

我正在使用gdb调试“Veracrypt”,因为我想知道使用Veracrypt挂载卷时调用的函数的顺序。由于Veracrypt使用多线程,我通过编写gdb选项“-g”修改了MakeFile,并使用了一些命令,如thread apply all bt fullset follow-fork-mode child等。我还尝试使用线程ID附加线程,例如sudo gdb -p [process ID]

所以我可以调试Veracrypt的代码,但我无法调试一些代码。

使用GDB,我已经验证了Veracrypt运行时要使用的多线程的线程ID(Volume Mount和Dismount进程),gdb显示了创建的线程的线程ID,如下所示。

[New Thread 0x7fffedf3e700 (LWP 5071)]
[New Thread 0x7fffed73d700 (LWP 5072)]
[New Thread 0x7fffecf3c700 (LWP 5073)]
[New Thread 0x7fffe7fff700 (LWP 5074)]
[New Thread 0x7fffe522f700 (LWP 5075)]
[New Thread 0x7fffe4a2e700 (LWP 5076)]
[New Thread 0x7fffdf568700 (LWP 5077)]
[New Thread 0x7fffded67700 (LWP 5078)]
[New Thread 0x7fffde566700 (LWP 5079)]
[Thread 0x7fffded67700 (LWP 5078) exited]
[New Thread 0x7fffded67700 (LWP 5081)]
[New Thread 0x7fffc9798700 (LWP 5082)]
[New Thread 0x7fffc8f97700 (LWP 5083)]
[New Thread 0x7fffc3fff700 (LWP 5084)]
[New Thread 0x7fffc37fe700 (LWP 5085)]
[New Thread 0x7fffc2ffd700 (LWP 5086)]
[Thread 0x7fffc3fff700 (LWP 5084) exited]
[Thread 0x7fffc2ffd700 (LWP 5086) exited]
[Thread 0x7fffc37fe700 (LWP 5085) exited]
[Thread 0x7fffded67700 (LWP 5081) exited]
[Thread 0x7fffc8f97700 (LWP 5083) exited]
[Thread 0x7fffc9798700 (LWP 5082) exited]
[New Thread 0x7fffc9798700 (LWP 5087)]
[New Thread 0x7fffc8f97700 (LWP 5088)]
[New Thread 0x7fffded67700 (LWP 5089)]
[New Thread 0x7fffc37fe700 (LWP 5090)]
[New Thread 0x7fffc3fff700 (LWP 5091)]
[Thread 0x7fffc9798700 (LWP 5087) exited]
[Thread 0x7fffc8f97700 (LWP 5088) exited]
[Thread 0x7fffc37fe700 (LWP 5090) exited]
[Thread 0x7fffc3fff700 (LWP 5091) exited]
[Thread 0x7fffde566700 (LWP 5079) exited]
[New Thread 0x7fffde566700 (LWP 5092)]
[New Thread 0x7fffc3fff700 (LWP 5093)]
[Thread 0x7fffc3fff700 (LWP 5093) exited]
[Thread 0x7fffded67700 (LWP 5089) exited]
[New Thread 0x7fffded67700 (LWP 5094)]
[Thread 0x7fffded67700 (LWP 5094) exited]
[New Thread 0x7fffded67700 (LWP 5095)]
[Thread 0x7fffded67700 (LWP 5095) exited]
[Thread 0x7fffedf3e700 (LWP 5071) exited]
[Thread 0x7fffed73d700 (LWP 5072) exited]
[Thread 0x7fffe7fff700 (LWP 5074) exited]
[Thread 0x7fffecf3c700 (LWP 5073) exited]
[Thread 0x7fffe522f700 (LWP 5075) exited]
[Thread 0x7ffff7fc4a40 (LWP 5066) exited]
[Thread 0x7fffdf568700 (LWP 5077) exited]
[Thread 0x7fffe4a2e700 (LWP 5076) exited]
[Inferior 1 (process 5066) exited normally]

我使用“fprintf(..)”和“getpid()”来编写在文件中运行Veracrypt(卷装载和卸载过程)时执行每个功能的线程ID。 (我在这一部分也有一个问题。因为在无法用gdb调试的功能代码中,“printf(...)”函数不会将值打印到终端,而是在功能代码中可以是调试后,该值将打印到终端。)

当我在使用“fprintf”函数生成的文件中检查执行我想要调试的函数的线程ID时,它不在gdb生成的线程ID列表中(上面的代码)并且有一个值大于列表中的线程ID。 (在这种情况下(上面的代码),执行我想要调试的函数的线程ID是5098)。

我想调试一些功能,例如CoreUnix.cpp::MountVolumeCoreLinux::MountVolumeNative。如何使用gdb调试这些函数?

1 个答案:

答案 0 :(得分:0)

  

我用过" fprintf(..)"和" getpid()"编写执行每个函数的线程ID

请注意,对于非古代版本的GLIBC(您似乎正在使用),getpid会返回进程ID,而不是线程ID。您可能希望改为使用gettid

  

因为在无法使用gdb调试的功能代码中," printf(...)"函数不会将值打印到终端,但在可以调试的功能代码中,该值将打印到终端。)

究竟是你的意思是"无法调试的功能"?

我怀疑你能够在该代码上设置断点,但断点永远不会被击中。如果是这样的话,听起来你正在调试错误的过程。一般来说,set follow-fork-mode child很少是人们想要的:创建孩子的过程通常会创建多个孩子,并且总是想要调试每个fork的第一个孩子是非常罕见的。