在SIGNAL中继续使用gdb中的python脚本

时间:2014-08-20 17:06:28

标签: python gdb

我正在尝试使用gdb中的python脚本生成有关分段错误(和其他信号)的一些输出。脚本如下所示:

import gdb

def event_handler(event):
    gdb.execute("set scheduler-locking on") # this is needed to avoid parallel exec of the handler

    gdb.write("\n[ME] SIG " + event.stop_signal)
    frame = gdb.selected_frame()
    while frame:
        gdb.write("\n[ME] FN " + str(frame.name()))
        frame = frame.older()

# make sure output goes to a file
gdb.execute("set logging on") 
gdb.execute("set logging file gdbout")
gdb.events.stop.connect(event_handler)

问题是我需要在每个分段错误上按c和Enter,脚本不会继续。

如果我这样做

gdb.execute("continue")
在处理程序中,我得到一个StackOverflow。我认为这是因为execute()永远不会返回。如果我做

handle SIGSEGV nostop

我的处理程序不再被调用。如何在处理程序后继续?

2 个答案:

答案 0 :(得分:5)

好的,我发现了怎么做:

首先,我需要一个可调用的continue命令。正如Tom所建议的那样,这将与post_event一起使用:

class Executor:
    def __init__(self, cmd):
        self.__cmd = cmd

    def __call__(self):
        gdb.execute(self.__cmd)

这是事件处理程序:

def event_handler(event):
    gdb.execute("set scheduler-locking on") # to avoid parallel signals in other threads

    gdb.write("\n[ME] SIG " + event.stop_signal)
    frame = gdb.selected_frame()
    while frame:
        gdb.write("\n[ME] FN " + str(frame.name()))
        frame = frame.older()
    gdb.execute("set scheduler-locking off") # otherwise just this thread is continued, leading to a deadlock   
    gdb.post_event(Executor("continue")) # and post the continue command to gdb

然后,调用它:

gdb.execute("set logging on")
gdb.execute("set logging file gdbout")
gdb.execute("set pagination off")
gdb.events.stop.connect(event_handler)

诀窍是稍后禁用调度程序锁定,需要避免并发问题,但如果没有运行处理程序,则会导致死锁。

答案 1 :(得分:1)

不幸的是,在gdb中仍然没有好的Python API信号。相反,你必须诉诸黑客。那就是说,你的方法对我来说似乎很好。

为了处理“继续”问题,我建议使用gdb.post_event将事件插入到gdb的事件队列中。该事件可以调用continue命令。这应该至少避免堆栈溢出问题。