Programatically interrupt gdb run - Stack Overflow

I am debugging a program that is supposed to run continuously. It gives a terminal that accepts user in

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
  • 1 If you start the program with run, it will only get to your next command shell sleep 3 when the program finished running. You might want to try Background Execution by using run& instead. – ssbssa Commented Jan 22 at 16:06
Add a comment  | 

2 Answers 2

Reset to default 1

Place 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

相关推荐

  • Programatically interrupt gdb run - Stack Overflow

    I am debugging a program that is supposed to run continuously. It gives a terminal that accepts user in

    12小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信