Debugging 硬件断点和软件断点之间有什么区别?

Debugging 硬件断点和软件断点之间有什么区别?,debugging,gdb,breakpoints,Debugging,Gdb,Breakpoints,硬件断点和软件断点之间有什么区别 硬件断点是否据说比软件断点快,如果是,那么如何,以及为什么我们需要软件断点?这篇文章很好地讨论了优缺点: 为了直接回答您的问题,软件断点更灵活,因为硬件断点在某些功能上受到限制,并且高度依赖于体系结构。本文给出的一个示例是x86硬件限制为4个硬件断点 硬件断点的速度更快,因为它们有专用寄存器,并且比软件断点的开销更小。您可以浏览一下,它很好地解释了硬件和软件断点 硬件断点需要MCU的支持。ARM控制器有特殊的寄存器,当PC(程序计数器)==sp寄存器CPU停止

硬件断点和软件断点之间有什么区别


硬件断点是否据说比软件断点快,如果是,那么如何,以及为什么我们需要软件断点?

这篇文章很好地讨论了优缺点:

为了直接回答您的问题,软件断点更灵活,因为硬件断点在某些功能上受到限制,并且高度依赖于体系结构。本文给出的一个示例是x86硬件限制为4个硬件断点

硬件断点的速度更快,因为它们有专用寄存器,并且比软件断点的开销更小。

您可以浏览一下,它很好地解释了硬件和软件断点

硬件断点需要MCU的支持。ARM控制器有特殊的寄存器,当PC(程序计数器)==sp寄存器CPU停止时,您可以在其中写入一些地址空间。Jtag通常需要写入这些特殊寄存器

在GDB中,通过插入陷阱、非法除法或其他会导致异常的指令来实现SW断点,然后当遇到异常时,GDB将接受异常并停止程序。当用户说要继续时,gdb将恢复原始指令,单步执行,重新插入陷阱,然后继续


与SW调试器相比,使用HW调试器有很多优点,尤其是在处理中断和内存总线设备时。AFAIK中断无法使用软件调试器进行调试。

除了上述答案之外,还需要注意的是,虽然软件断点覆盖程序中的特定指令以知道在何处停止,但更有限的硬件断点实际上是处理器的一部分


Justin Seitz在他的书中指出,这里的重要区别在于,通过覆盖指令,软件断点实际上会改变文件的大小,因此任何类型的程序,例如计算其CRC的恶意软件,都可以根据设置的断点改变其行为,而对于硬件断点,调试器停止并单步执行某些代码块的情况就不那么明显了。

简而言之,硬件断点使用专用寄存器,因此数量有限。可以在易失性和非易失性存储器上设置这些参数

通过使用断点指令替换RAM内存中指令的操作码来设置软件断点。这些只能在RAM内存中设置(闪存无法写入),且不受限制

感谢和问候,
Shivakumar V W

硬件断点实际上是比较器,将当前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)允许使用断点指令对闪存重新编程,而aso允许无限数量的(软件)断点,即使在调试闪存中的程序时也是如此


观察点

在这种情况下,硬件处理速度要快得多:

watch var
rwatch var
awatch var
在GDB 7.7 x86-64上输入这些命令时,会显示:

Hardware watchpoint 2: var
x86的此硬件功能在以下内容中提到:

这可能是因为现有的分页电路,它管理每个内存访问

“软件”的替代方案是,这是非常缓慢的


将其与常规断点进行比较,在常规断点中,至少软件实现会插入和
int3指令并让程序运行,因此只有在遇到断点时才需要支付开销。

英特尔系统调试器帮助文档中的一些引用:

硬件与软件断点的对比 调试器可以同时使用这两种硬件 和软件断点,每个断点都有优点和缺点:

硬件断点使用DRx体系结构实现 英特尔SDM中描述的断点寄存器。他们有 重置时可直接使用、非易失性和 可与闪存或其他只读存储器一起使用。缺点是 他们是一种有限的资源软件断点需要 通过替换 使用特殊指令在所需位置执行操作码。这使得 它们是一个无限的资源,但是内存依赖性意味着你不能 在将模块加载到内存中之前安装它们,如果 目标软件将覆盖该内存,然后它们将变得无效。 通常,必须由调试器启用的任何调试功能 重置后不会持续,并可能在其他重置后受到影响 拱门