3

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

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

由于分配了大量实例(超过 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 的文档建议你不应该做我正在做的事情。我相信这可以解释为什么该程序正在楔入

功能:Breakpoint.stop ( self )

...

您不应该更改下级的执行状态(即 step、next 等),更改当前帧上下文(即更改当前活动帧),或更改、添加或删除任何断点

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

#!/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")

关于如何从断点操作观察点的任何想法?

(或有关如何调试此问题的任何其他想法?)

4

0 回答 0