【问题标题】:How to debug multi thread using GDB?如何使用 GDB 调试多线程?
【发布时间】:2017-08-17 16:17:36
【问题描述】:

我正在使用 gdb 调试“Veracrypt”,因为我想知道使用 Veracrypt 挂载卷时调用的函数的顺序。由于 Veracrypt 使用多线程,我通过编写 gdb 选项“-g”修改了 MakeFile,并使用了一些命令,例如 thread apply all bt fullset follow-fork-mode child 等。我还尝试使用sudo gdb -p [process ID]等线程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(...)”函数并没有把值打印到终端,而是在能用gdb调试的函数代码中调试后,将值打印到终端。)

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

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

【问题讨论】:

    标签: debugging gdb


    【解决方案1】:

    我用“fprintf(..)”和“getpid()”写出了执行每个函数的线程ID

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

    因为在不能用gdb调试的函数代码中,“printf(...)”函数没有将值打印到终端,但是在可以调试的函数代码中,将值打印到终端。)

    究竟你所说的“无法调试的功能”是什么意思?

    我怀疑您可以在该代码上设置断点,但断点永远不会被命中。如果是这种情况,听起来您正在调试错误的进程。一般来说,set follow-fork-mode child 很少是人们想要的:创建子进程的进程通常会创建多个子进程,并且总是希望在每个 fork 处调试第一个子进程的情况非常罕见。

    【讨论】:

    • 我也使用了“gettid()”,但它的值与getpid()的值相同。而“无法调试的函数”的确切含义是,它是Veracrypt的一个函数代码,它通过使用用于调试多线程的选项不会在断点处停止,而是在Veracrypt的挂载过程中运行。
    猜你喜欢
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2011-11-29
    • 1970-01-01
    • 2021-11-02
    相关资源
    最近更新 更多