I am debugging a program that is supposed to run continuously. It gives a terminal that accepts user input and reacts to it.
It's randomly segfaulting at startup and I want to debug it by spawning a run, waiting for 3 seconds, interrupting it and spawning another run until it segfaults. I tried something like:
(gdb) while (1)
>run
>shell sleep 3
>interrupt
>end
But this does not interrupt my application after 3 seconds. If instead I do something like:
(gdb) while (1)
>run
>end
The application runs in a loop but I have to keep pressing Ctrl+C to manually interrupt it and when it segfaults it automatically restarts so I can't debug it.
Is there a way to manually interrupt it until it segfaults? What is a good way to do this?
I am debugging a program that is supposed to run continuously. It gives a terminal that accepts user input and reacts to it.
It's randomly segfaulting at startup and I want to debug it by spawning a run, waiting for 3 seconds, interrupting it and spawning another run until it segfaults. I tried something like:
(gdb) while (1)
>run
>shell sleep 3
>interrupt
>end
But this does not interrupt my application after 3 seconds. If instead I do something like:
(gdb) while (1)
>run
>end
The application runs in a loop but I have to keep pressing Ctrl+C to manually interrupt it and when it segfaults it automatically restarts so I can't debug it.
Is there a way to manually interrupt it until it segfaults? What is a good way to do this?
Share Improve this question asked Jan 22 at 15:15 Marco Montevechi FilhoMarco Montevechi Filho 1932 silver badges15 bronze badges 1 |2 Answers
Reset to default 1Place the following into a file called run_and_interrupt.py
:
import threading
import time
import os
import signal
# A thread calss which waits for DELAY seconds then sends SIGINT to
# process PID.
class interrupting_thread(threading.Thread):
def __init__(self, delay, pid):
threading.Thread.__init__(self)
self.delay = delay
self.pid = pid
def run(self):
time.sleep(self.delay)
os.kill(self.pid, signal.SIGINT)
# The last signal that stopped the inferior.
last_stop_signal = "SIGINT"
# Handle stop events. Look for signal stops and record the signal
# into the global LAST_STOP_SIGNAL.
def stop_handler(event):
global last_stop_signal
if isinstance(event, gdb.SignalEvent):
last_stop_signal = event.stop_signal
# Register the stop event handler.
gdb.events.stop.connect(stop_handler)
class run_and_interrupt(gdb.Command):
"""run-and-interrupt ARGS
Run the current inferior passing in ARGS.
"""
def __init__(self):
gdb.Command.__init__(self, "run-and-interrupt", gdb.COMMAND_RUNNING)
def invoke(self, args, from_tty):
global last_stop_signal
while last_stop_signal == "SIGINT":
gdb.execute(f"starti {args}")
inf = gdb.selected_inferior()
pid = inf.pid
# Start a new thread.
thr = interrupting_thread(3, pid)
thr.start()
gdb.execute("continue")
thr.join()
# Register the new command.
run_and_interrupt()
Then in a GDB session source run_and_interrupt.py
.
You now have a new GDB command run-and-interrupt
which will start the current executable, wait 3 seconds, then send SIGINT to the inferior.
The command does this repeatedly until the inferior doesn't stop with SIGINT.
The Python code is a little rough, and can certainly be improved, but this should be a good starting point.
I want to debug it by spawning a run, waiting for 3 seconds, interrupting it and spawning another run until it segfaults.
A much easier solution: modify the application itself. Presumably it looks something like this:
int main(int argc, char *argv[])
{
Initialize();
return ProcessInputs(); // event loop
}
Then you could add exit(0)
before ProcessInputs()
(or wherever it's appropriate). You wouldn't even have to wait 3 seconds, making retry loop faster.
An even better idea might be to enable core
dumps and look at the core
-- it should be pretty clear where it's crashing.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745331723a4622911.html
run
, it will only get to your next commandshell sleep 3
when the program finished running. You might want to try Background Execution by usingrun&
instead. – ssbssa Commented Jan 22 at 16:06