断点在C++;密码? 如何断点在C++代码中工作?在编译代码时,它们是插入到某些汇编指令之间的特殊指令吗?或者还有其他的东西吗?另外,代码是如何实现的?与断点相同…?
根据technochakra.com上的说法,您是正确的: 软件断点通过在被调试的程序中插入特殊指令来工作。英特尔平台上的这条特殊指令是“int 3”。执行时,它调用调试器的异常处理程序 不过,我不确定如何执行下一条指令。不过,本文接着补充道: 出于实际原因,在添加或删除断点时要求重新编译是不明智的。调试器会在内存中更改加载的可执行文件映像,并在运行时插入“int 3”指令断点在C++;密码? 如何断点在C++代码中工作?在编译代码时,它们是插入到某些汇编指令之间的特殊指令吗?或者还有其他的东西吗?另外,代码是如何实现的?与断点相同…?,c++,debugging,breakpoints,C++,Debugging,Breakpoints,根据technochakra.com上的说法,您是正确的: 软件断点通过在被调试的程序中插入特殊指令来工作。英特尔平台上的这条特殊指令是“int 3”。执行时,它调用调试器的异常处理程序 不过,我不确定如何执行下一条指令。不过,本文接着补充道: 出于实际原因,在添加或删除断点时要求重新编译是不明智的。调试器会在内存中更改加载的可执行文件映像,并在运行时插入“int 3”指令 但是,这只适用于“Runto to RealLayObjyPosivices”。在C++(C++)级(汇编)代码级实现。单
<>但是,这只适用于“Runto to RealLayObjyPosivices”。
在C++(C++)级(汇编)代码级实现。单步执行器知道如何将C++代码行映射到代码地址。 有不同的实现。有一些CPU支持使用断点寄存器进行调试。当执行到达断点寄存器中的地址时,CPU执行断点异常
另一种方法是在执行时使用一条特殊指令(最多一条单字节指令)修补代码第一种方法允许在ROM中使用断点,第二种方法允许同时使用更多断点。这在很大程度上取决于CPU和调试器 例如,x86 CPU上可能的解决方案之一:
- 在所需位置插入一个字节的INT3指令
- 等待断点异常出现
- 将异常地址与断点列表进行比较,以确定是哪个断点
- 执行断点操作
- 将INT3替换为原始字节,并将调试后的进程切换到跟踪模式(逐步执行CPU指令)
- 继续调试进程
- 立即捕获跟踪异常-指令已执行
- 把INT3放回去
出于这些原因,在终止调试会话之前,让调试器有机会删除它设置的所有断点是很重要的。在进程的运行时,调试器会动态地注入断点。我希望这也会影响代码的执行。但我不是100%肯定我对此很感兴趣。@gablin,你介意我们把问题编辑成关于“本机”代码而不是“C++”的问题吗?这几乎是同一个问题,更好地反映了你的答案。@StevenFisher:不,请继续。=)“在终止调试会话之前,让调试器有机会删除它设置的所有断点,这一点很重要。"不——调试器只修改内存中的映像,而不是磁盘上的原始文件。事实上,如果您结束调试器并让程序继续运行,它必须先删除内存中的断点,然后再让程序运行。如果您的程序代码大于内存,怎么办?可能gdb使用带有MAP_PRIVATE的mmap来防止断点碰到disk…我不明白“用原始字节替换INT3”部分…为什么我们需要这样做?从断点恢复后,您需要在停止的位置执行CPU指令,但您损坏了它-将第一个字节替换为INT3操作码。因此,您需要恢复它,让CPU处理该指令,然后将INT3放回-所以下次执行此指令时,您会再次中断不,我明白了。这就是调试器在代码中“注入”断点的方式。谢谢!引用操作码
0xCC
,因此如果我们在调试器上使用操作码的当前示例,将采用指令B0 61
(MOV AL,61h
),存储第一个字节(B0
)并将其替换为CC
生成操作码CC 61
。当CPU读取此指令时,程序中断并跳转到调试器中。其余为历史记录。。。↑