I am trying to generate some output on segmentation faults (and other signals) with a python script in gdb. The script looks like this:
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)
The problem is that I need to press c and Enter on every segmentation fault, the script does not continue.
If I do
gdb.execute("continue")
in the handler, I get a StackOverflow. I think this is because execute() never returns. If I do
handle SIGSEGV nostop
My handler is not invoked any longer. How can I continue after the handler?
Okay, I found out how to do it:
First, I need a callable for the continue command. As suggested by Tom, this will be used with post_event:
class Executor:
def __init__(self, cmd):
self.__cmd = cmd
def __call__(self):
gdb.execute(self.__cmd)
And here is the event handler:
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
And then, to invoke it:
gdb.execute("set logging on")
gdb.execute("set logging file gdbout")
gdb.execute("set pagination off")
gdb.events.stop.connect(event_handler)
The trick is to disable scheduler-locking later, it is needed to avoid concurrency problems, but it leads to a deadlock if no handler is running.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With