硬件断点实际上是比较器,比较当前PC与比较器中的地址(启用时)。硬件断点是设置断点时的最佳解决方案。通常通过调试探针设置(使用JTAG、SWD等)。硬件断点的缺点:它们是有限的。CPU只有有限数量的硬件断点(比较器)。可用硬件断点的数量取决于CPU。ARM 7/9核心有2个,现代ARM设备(Cortex-M 0,3,4)在2到6个之间,x86通常是4个。 软件断点实际上是通过用断点指令替换要被断点的指令来设置的。断点指令存在于大多数CPU中,并且通常与最短指令一样短,因此在x86上只有一个字节(0xcc,INT 3)。在Cortex-M CPU上,指令是2或4字节,因此断点指令是2字节指令。 如果程序位于RAM中(例如PC上),则可以轻松设置软件断点。许多嵌入式系统都将程序存储在闪存中。在这里,交换指令不是那么容易,因为闪存需要重新编程,所以主要使用硬件断点。如果程序位于闪存中,大多数调试探测仅支持硬件断点。然而,一些(例如SEGGER的J-Link)允许使用断点指令对闪存进行重新编程,并且即使在调试位于闪存中的程序时也允许无限数量的(软件)断点。 More info about software breakpoints in flash memory
除了上面的答案,还需要注意的是,虽然软件断点会覆盖程序中的特定指令,以知道在哪里停止,但数量更有限的硬件断点实际上是处理器的一部分。 Justin Seitz在他的书Gray Hat Python中指出,这里的重要区别在于,通过重写指令,软件断点实际上改变了文件的CRC,因此任何类型的程序,例如计算其CRC的恶意软件,都可以响应于设置的断点而改变其行为。而对于硬件断点,调试器停止并单步执行某些代码块不太明显。
9条答案
按热度按时间qv7cva1a1#
这篇文章提供了一个很好的利弊讨论:http://www.nynaeve.net/?p=80
直接回答您的问题,软件断点更灵活,因为硬件断点在某些功能上受到限制,并且高度依赖于体系结构。文章中给出的一个例子是x86硬件有4个硬件断点的限制。
硬件断点速度更快,因为它们具有专用寄存器,并且比软件断点开销更少。
zbq4xfa02#
硬件断点实际上是比较器,比较当前PC与比较器中的地址(启用时)。硬件断点是设置断点时的最佳解决方案。通常通过调试探针设置(使用JTAG、SWD等)。硬件断点的缺点:它们是有限的。CPU只有有限数量的硬件断点(比较器)。可用硬件断点的数量取决于CPU。ARM 7/9核心有2个,现代ARM设备(Cortex-M 0,3,4)在2到6个之间,x86通常是4个。
软件断点实际上是通过用断点指令替换要被断点的指令来设置的。断点指令存在于大多数CPU中,并且通常与最短指令一样短,因此在x86上只有一个字节(0xcc,INT 3)。在Cortex-M CPU上,指令是2或4字节,因此断点指令是2字节指令。
如果程序位于RAM中(例如PC上),则可以轻松设置软件断点。许多嵌入式系统都将程序存储在闪存中。在这里,交换指令不是那么容易,因为闪存需要重新编程,所以主要使用硬件断点。如果程序位于闪存中,大多数调试探测仅支持硬件断点。然而,一些(例如SEGGER的J-Link)允许使用断点指令对闪存进行重新编程,并且即使在调试位于闪存中的程序时也允许无限数量的(软件)断点。
More info about software breakpoints in flash memory
mwngjboj3#
你可以通过GDB internals,它很好地解释了硬件和软件断点。
硬件断点需要MCU的支持。ARM控制器有特殊的寄存器,每当PC(程序计数器)== sp寄存器CPU停止时,您可以写入一些地址空间。JTAG通常需要写入那些特殊的寄存器。
SW断点在GDB中通过插入陷阱、非法除法或其他会导致异常的指令来实现,然后当遇到异常时,gdb将接受异常并停止程序。当用户说要继续时,gdb将恢复原始指令,单步执行,重新插入陷阱,然后继续。
与软件调试器相比,使用硬件调试器有很多优点,尤其是在处理中断和内存总线设备时。AFAIK中断不能用软件调试器进行调试。
wpx232ag4#
除了上面的答案,还需要注意的是,虽然软件断点会覆盖程序中的特定指令,以知道在哪里停止,但数量更有限的硬件断点实际上是处理器的一部分。
Justin Seitz在他的书Gray Hat Python中指出,这里的重要区别在于,通过重写指令,软件断点实际上改变了文件的CRC,因此任何类型的程序,例如计算其CRC的恶意软件,都可以响应于设置的断点而改变其行为。而对于硬件断点,调试器停止并单步执行某些代码块不太明显。
ehxuflar5#
简而言之,硬件断点利用专用寄存器,因此数量有限。这些可以在易失性和非易失性存储器上设置。
软件断点是通过用断点指令替换RAM存储器中指令的操作码来设置的。这些只能在RAM存储器中设置(闪存不适合写入),不受限制。
This article provides good explanation about breakpoints.
感谢和问候,Shivakumar V W
fcg9iug36#
软件断点在RAM中放置一条指令,当程序到达该地址时,该指令将像TRAP一样执行。
而硬件断点使用CPU的寄存器来实现断点本身。这就是为什么硬件断点要快得多的原因。这就是为什么我们需要软件断点:硬件断点被限制为专用于断点的寄存器的处理器数量。
今天在工作中学到了:)
k97glaaz7#
Watchpoints是它产生巨大差异的地方
这是硬件处理快得多的情况:
字符串
当您在GDB 7.7 x86-64上输入这些命令时,它会说:
型
x86的这种硬件功能在以下位置提到:http://en.wikipedia.org/wiki/X86_debug_register
这可能是因为现有的分页电路,它管理每个存储器访问。
“软件”的替代方案是single step the program,这是 * 非常 * 慢。
与常规断点相比,至少软件实现会在断点处注入
int3
指令并让程序运行,因此您只需在命中断点时支付开销。hmmo2u0o8#
英特尔系统调试器帮助文档中的一些引用:
硬件与软件断点调试器可以使用硬件和软件断点,每种断点都有优点和缺点:
硬件断点使用英特尔SDM中描述的DRx体系结构断点寄存器实现。它们具有在复位时可直接使用、非易失性以及可与闪存或其他只读存储器一起使用的优点。缺点是它们是有限的资源。软件断点需要修改系统内存,因为它们是通过用特殊指令替换所需位置的操作码来实现的。这使它们成为无限的资源,但内存依赖性意味着您不能在模块加载到内存之前安装它们,如果目标软件覆盖该内存,则它们将变得无效。通常,必须由调试器启用的任何调试特征在重置之后不持续,并且可能在诸如SMM进入/退出或VM进入/退出之类的其他架构模式转变之后受到影响。具体示例包括:
CPU复位将清除除复位中断之外的所有调试功能。例如,这意味着用户指定的断点将无效,直到目标在重置后暂停一次。请注意,此暂停可能是由于重置中断或用户启动的暂停。无论哪种情况,调试器都将恢复必要的调试功能。SMM Entry/exit将禁用/重新启用断点,这意味着当在SMRAM外部停止时,您无法在SMRAM中指定断点。如果您希望在SMRAM内中断,则必须首先在SMM进入中断处停止,然后手动应用断点。或者,您可以修补BIOS,以便在进入SMM时重新启用断点,但这需要能够修改生产代码中无法使用的BIOS。
yhived7q9#
硬件断点的数量有限,并利用专门的硬件功能来提高性能。它们通常用于低级调试任务。另一方面,软件断点可以设置在多个位置,并且用途更广,使其适用于高级代码和应用程序。但是,由于需要额外的处理来处理断点中断,它们可能会更慢。
开发人员根据他们的调试需要和正在处理的代码级别选择适当的类型。