通过 python 接口在 gdb 中的断点处执行命令

Executing commands at breakpoint in gdb via python interface

不是 this question 的副本,因为我正在通过 python 接口连接到 gdb。
This one 类似但没有答案。

我在 python 中扩展了一个 gdb.breakpoint 以便它将某些寄存器写入文件,然后跳转到一个地址:在 0x4021ee,我想写东西到文件,然后跳转到 0x4021f3

但是,command 中的任何内容都不会被执行。

import gdb
class DebugPrintingBreakpoint(gdb.Breakpoint):
    def __init__(self, spec, command):
        super(DebugPrintingBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT, internal = False)
        self.command = command

    def stop(self):
        with open('tracer', 'a') as f:
            f.write(chr(gdb.parse_and_eval("$rbx") ^ 0x71))
            f.close()
        return False



gdb.execute("start")
DebugPrintingBreakpoint("*0x4021ee", "jump *0x4021f3")
gdb.execute("continue")

如果我明确地将 gdb.execute(self.command) 添加到 stop() 的末尾,我会得到 Python Exception <class 'gdb.error'> Cannot execute this command while the selected thread is running.:

有人在 python gdb 中有带断点的命令列表的工作示例吗?

Breakpoint.stop 方法被调用时,在 gdb 术语中,劣势仍然是 "executing"。这在一定程度上是一种簿记上的怪事——当然,下级并没有真正执行,它在 gdb 执行一些与断点相关的处理时停止了。在内部,它更像是 gdb 尚未决定向 gdb 内部的其他相关方报告停止。这种有趣的状态让 stop 相对于 next 和其他执行命令如此出色地工作。

gdb 中的某些命令无法调用,而下级是 运行,如 jump,如您所见。

您可以尝试一件事——我从未尝试过,不知道它是否可行——是在您的 stop 方法中分配给 PC。这可能做对了;但是你当然应该知道文档警告不要做这样奇怪的事情。

如果失败,我认为唯一的方法是退回到使用 commandsjump 附加到断点。这样做的缺点是会干扰 next.

最后一种方法是修补 运行 代码以插入一个跳转或仅插入一个 nop 序列。

尝试几个选项:

  1. 使用 gdb.post_event 从 stop() 到 运行 稍后所需的命令。我相信您需要从函数中 return True 然后从事件中调用 continue。
  2. 创建一个普通的断点并监听events.stop检查你的断点是否被命中。