Python 如何在gdb上的断点后添加软件监视点

Python 如何在gdb上的断点后添加软件监视点,python,c,gdb,breakpoints,watchpoint,Python,C,Gdb,Breakpoints,Watchpoint,我试图调试一个C程序,该程序在其生命周期内分配和释放特定结构的各种实例。在某个时候,其中一个实例正在被破坏 为了调试它,我想在分配这些结构后不久设置观察点,并在它们释放前不久删除观察点。为此,我编写了一个python gdb脚本(见下文),它实现了gdb.Breakpoint的两个子类:BreakpointAlloc()和BreakpointFree()。前者有一个stop()方法,在分配的结构上添加一个观察点;后者有一个stop()方法,删除观察点。(监视点保存在dict中,由包含分配实例地址

我试图调试一个C程序,该程序在其生命周期内分配和释放特定结构的各种实例。在某个时候,其中一个实例正在被破坏

为了调试它,我想在分配这些结构后不久设置观察点,并在它们释放前不久删除观察点。为此,我编写了一个python gdb脚本(见下文),它实现了
gdb.Breakpoint
的两个子类:
BreakpointAlloc()
BreakpointFree()
。前者有一个
stop()
方法,在分配的结构上添加一个观察点;后者有一个
stop()
方法,删除观察点。(监视点保存在dict中,由包含分配实例地址的字符串索引。)

由于分配了大量实例(超过100个),我无法使用硬件观察点。但是,当使用软件观察点时(首先运行
gdb.execute(“set can use hw watchpoints 0”)
),程序似乎有问题,我不知道发生了什么

#!/usr/bin/env python

import gdb

wps = {}

def BreakpointAlloc(gdb.Breakpoint):
  def stop(self):
    ptr = gdb.parse_and_eval("ptr").address
    wp = gdb.Breakpoint("*({0})({1})".format(ptr.type, ptr), gdb.BP_WATCHPOINT)
    wps["{0}".format(ptr)] = wp
    return False

def BreakpointFree(gdb.Breakpoint):
  def stop(self):
    ptr = gdb.parse_and_eval("ptr").address
    wp = wps["{0}".format(ptr)]
    wp.delete()
    del wps["{0}".format(wp)]
    return False

bp_alloc = BreakpointAlloc("prog.c:111")
bp_free = BreakpointFree("prog.c:222")
gdb.execute("set can-use-hw-watchpoints 0")
gdb python API的文档建议您不应该做我正在做的事情。我相信这可以解释为什么该计划是楔入式的:

功能:断点。停止(self)

您不应更改次帧的执行状态(即步骤、下一步等)、更改当前帧上下文(即更改当前活动帧)或更改、添加或删除任何断点

考虑到文档,我还尝试修改我的程序,通过停止事件添加/删除观察点(见下文)。当使用软件监视点时,同样的问题也会出现:程序似乎有问题

关于如何在断点之外操纵监视点,有什么想法吗


(或者关于如何调试这个问题的任何其他想法?

如果可能的话,尝试使用
valgrind
rr
。@velkan:我以前尝试过用gdb录制完整的
record full
,但它不起作用,因为我的程序是多线程的。将进一步查看
rr
并尝试
valgrind
#!/usr/bin/env python

import gdb

wps = {}

bp_alloc = gdb.Breakpoint("prog.c:111")
bp_free = gdb.Breakpoint("proc.c:222")

def stopAlloc():
  ptr = gdb.parse_and_eval("ptr").address
  wp = gdb.Breakpoint("*({0})({1})".format(ptr.type, ptr), gdb.BP_WATCHPOINT)
  wps["{0}".format(ptr)] = wp

def stopFree():
  ptr = gdb.parse_and_eval("ptr").address
  wp = wps["{0}".format(ptr)]
  wp.delete()
  del wps["{0}".format(ptr)]

def handleStop(stopEvent):
  for bp in stopEvent.breakpoints:
    if bp == bp_alloc:
      stopAlloc()
    elif bp == bp_free:
      stopFree()

gdb.events.stop(handleStop)
gdb.execute("set can-use-hw-watchpoints 0")