我正在尝试调试一个C程序,该程序在其生命周期内分配和释放特定结构的各种实例。在某些时候,其中一个实例正在被破坏。
要调试它,我想在分配这些结构后立即设置观察点 之前 它们是免费的。为此,我编写了一个python gdb脚本(见下文),该脚本实现了gdb.Breakpoint
的两个子类:BreakpointAlloc()
和BreakpointFree()
。前者有一个stop()
方法,它在分配的结构上添加一个观察点,后者有一个stop()
方法,用于删除观察点。 (观察点保存在由包含分配实例的地址的字符串索引的字典中。)
由于分配了大量实例(超过100个),我无法使用硬件观察点。但是,当使用软件观察点(首先运行gdb.execute("set can-use-hw-watchpoints 0")
)时,程序似乎 wedge ,我无法分辨出发生了什么。
#!/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的文档表明你不应该做我正在做的事情。我相信这可以解释为什么程序 wedging :
功能: Breakpoint.stop ( self )
...
你不应该改变下级的执行状态(即步骤,下一步等),改变当前帧上下文(即,改变当前活动帧),或改变,添加或删除任何断点
考虑到文档,我还尝试修改我的程序,通过停止事件添加/删除观察点(见下文)。使用软件观察点时,会出现同样的问题:程序似乎 wedge 。
#!/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")
关于如何操纵断点的观察点的任何想法?
(或者有关如何调试此问题的任何其他想法?)