我试图用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)
Run Code Online (Sandbox Code Playgroud)
问题是我需要在每个分段错误上按c和Enter,脚本不会继续.
如果我做
gdb.execute("continue")
Run Code Online (Sandbox Code Playgroud)
在处理程序中,我得到一个StackOverflow.我认为这是因为execute()永远不会返回.如果我做
handle SIGSEGV nostop
Run Code Online (Sandbox Code Playgroud)
我的处理程序不再被调用.如何在处理程序后继续?
好的,我发现了怎么做:
首先,我需要一个可调用的continue命令.正如Tom所建议的,这将与post_event一起使用:
class Executor:
def __init__(self, cmd):
self.__cmd = cmd
def __call__(self):
gdb.execute(self.__cmd)
Run Code Online (Sandbox Code Playgroud)
这是事件处理程序:
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
Run Code Online (Sandbox Code Playgroud)
然后,调用它:
gdb.execute("set logging on")
gdb.execute("set logging file gdbout")
gdb.execute("set pagination off")
gdb.events.stop.connect(event_handler)
Run Code Online (Sandbox Code Playgroud)
诀窍是稍后禁用调度程序锁定,需要避免并发问题,但如果没有运行处理程序,则会导致死锁.