基本问题&我是C / C ++和GDB的新手。
我们使用GDB来调试进程。我们将GDB附加到进程,然后指定filename.c以及行号以放置断点。
我的问题是“在我们将GDB连接到正在运行的进程后,GDB或操作系统或其他任何可能知道它必须在指定的行号(在filename.c中)中断?”
比如说,当前进程是在调试模式下运行并且应用了断点并且流程执行必须在那时中断(等待用户输入)?
答案 0 :(得分:9)
如果程序在特定点停止或崩溃,调试器可以告诉您程序中该点的位置。
要使这两个工作,程序二进制文件必须包含其他调试信息,这些信息将程序映像中的地址与源代码中的位置(源文件和行号)相关联。
要在特定行添加断点,调试器会找到最接近该行的程序地址,修改内存中可执行文件的副本,在该位置插入一条特殊的“break”指令,这将导致程序的执行被中断,然后“跟踪”程序的执行并等待它到达断点并停止。
有关详细信息,请参阅http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1/和http://www.howzatt.demon.co.uk/articles/SimplePTrace.html
答案 1 :(得分:6)
我无法评论最新版本的gdb - 但是许多调试器实际上使用中断指令在所需的断点位置(在内存中)交换汇编指令。这会“唤醒”调试器,此时控制器会进行控制。
使用替代中断指令意味着CPU可以全速执行程序并在所需位置“绊倒”。
然而,现代处理器非常复杂,并且可能具有更优越的调试功能。
答案 2 :(得分:1)
GDB知道你的代码:它知道所有相关信息。在一行设置断点时,GDB获取等效的机器指令地址:所有代码(作为机器指令)都加载到内存中,因此代码的指令都有一个地址。
所以现在GDB知道你要破解的指令的地址。当您运行程序时,GDB将使用ptrace,它允许GDB在执行之前“看到”每条指令。然后,GDB只需查看当前指令(将执行的指令)是否与您的指令相同(您想要中断)。
答案 3 :(得分:-2)
如果在gcc / g ++中使用了-g选项,则每个源文件的行号都会附加到生成的目标文件中的指令中。