代码之家  ›  专栏  ›  技术社区  ›  Michael

gdb如何在共享库函数中设置软件断点?

  •  8
  • Michael  · 技术社区  · 12 年前

    我知道 software breakpoints 在一个可执行文件中,可以通过用另一个汇编指令替换所需位置的某些汇编指令来工作,这会导致中断。所以调试器可以在这个地方停止执行,用原始指令替换这个指令,并询问用户下一步该做什么,或者调用一些命令等等。

    但这种可执行文件的代码不被其他程序使用,并且在内存中只有一个副本。 软件断点如何与共享库一起工作? 例如,如果我在C库的某个内部函数上设置了一个断点(据我所知,它对所有应用程序只有一个副本,所以我们不能只替换其中的一些指令),那么软件断点是如何工作的?是否有任何用于此目的的“软件断点”技术?

    1 回复  |  直到 12 年前
        1
  •  10
  •   Iwillnotexist Idonotexist    12 年前

    Linux的答案是,Linux内核实现了COW(写时复制):如果共享库的代码被写入,内核会首先创建共享页面的私有副本,然后在内部重新映射虚拟内存 就为了这个过程 并允许应用程序继续。这对于userland应用程序是完全不可见的,并且完全在内核中完成。

    因此,在第一次将软件断点放入共享库之前,它的代码实际上是 共享 ; 但是 之后 不此后,该进程使用一个脏的但私有的副本进行操作。

    这种内核魔力使调试器不会导致其他应用程序突然停止。

    然而,在VxWorks等操作系统上,这是不可能的。根据个人经验,当我为VxWorks实现GDB远程调试服务器时,我不得不禁止我的用户在 semTake() semGive() (OS信号量函数),因为a)GDB在其源代码级单步实现中使用软件断点,b)VxWorks使用信号量来保护其断点列表。。。

    令人不快的结果是一场中断风暴,其中一个断点会导致中断,而在这个中断中会有另一个中断,而另一个和另一个在一个不可中断的链中,甚至对Ctrl-Z都有抵抗力。唯一的出路是关掉机器。

    推荐文章