GDB 如何知道它必须在指定的断点处中断?

Posted

技术标签:

【中文标题】GDB 如何知道它必须在指定的断点处中断?【英文标题】:how GDB knows it has to break at specified break point? 【发布时间】:2013-06-07 15:03:52 【问题描述】:

一个基本问题,我对 C/C++ 和 GDB 非常陌生。

我们使用 GDB 来调试进程。我们将 GDB 附加到一个进程,然后指定 filename.c 以及行号来放置断点。

我的问题是“在我们将 GDB 连接到正在运行的进程之后,GDB 或操作系统或其他任何东西如何知道它必须在指定的行号(在 filename.c 中)中断?”

会出现什么情况,例如,当前进程在调试模式下运行并应用断点,而此时进程执行必须中断(等待用户输入)?

【问题讨论】:

看看ptrace(2) @nouney:这将是一个很好的答案的良好基础。 【参考方案1】:

如果您的程序在特定点停止或崩溃,调试器可以告诉您该点在程序中的哪个位置。

为了使这两个工作正常,程序二进制文件必须包含额外的调试信息,将程序映像中的地址与源代码中的位置(源文件和行号)相关联。

要在特定行添加断点,调试器会找到最接近该行的程序地址,修改内存中可执行文件的副本以在该位置插入特殊的“break”指令,这将导致程序的执行被中断,然后“跟踪”程序的执行并等待它到达断点并停止。

更多详情见http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1/和http://www.howzatt.demon.co.uk/articles/SimplePTrace.html

【讨论】:

在许多架构(例如 x86)上,调试寄存器允许在不修改程序文本的情况下设置(少数)断点。【参考方案2】:

我无法评论最新版本的 gdb - 但许多调试器实际上将所需断点位置(内存中)的汇编指令与中断指令交换。这会“唤醒”此时控制的调试器。

使用替代中断指令意味着 CPU 可以全速执行您的程序并在所需位置“跳闸”。

然而,现代处理器非常复杂,并且可能具有更出色的调试功能。

【讨论】:

【参考方案3】:

GDB 知道您的代码:它知道一切。当您在一行设置断点时,GDB 会获取等效的机器指令地址:您的所有代码(作为机器指令)都加载到内存中,因此您的代码指令有一个地址。

所以现在 GDB 知道你要中断的指令的地址。当您运行程序时,GDB 将使用 ptrace,它允许 GDB 在执行之前“查看”每条指令。然后 GDB 只需查看当前指令(将被执行)是否与您的指令(您想要中断的指令)相同。

【讨论】:

您描述的方法是可行的,但速度太慢(1000 倍或更多)以至于在实践中无法使用。这不是可用的调试器实际上工作的方式。 我同意...这太慢了

以上是关于GDB 如何知道它必须在指定的断点处中断?的主要内容,如果未能解决你的问题,请参考以下文章

linux下使用gdb的断点设置

Linux编程基础——GDB(设置断点)

Linux编程基础——GDB(设置断点)

GDB:断点没有被命中

工具篇之GDB调试器用法

如何使用GDB调试多线程