是否可以在异常(SEGFAULT)错误后自动重新启动程序

Is it possible to automaticly restart program in GDB after exception (segfault) error?

本文关键字:错误 程序 重新启动 SEGFAULT 异常 是否      更新时间:2023-10-16

如何使用GDB在C 中运行程序,以便在错误异常(Segfaults)的情况下重新启动程序(我希望GDB自动使用"运行"命令),并且在同时,将任何错误记录到文件(命令" where")。

是否可能?

让我向您展示一个示例,该示例以3次重新启动程序,以防它崩溃。我使用Python脚本来处理Sigsegv(https://sourceware.org/gdb/onlinedocs/gdb/events-in-python.html)。

首先,这是GDB会话的一个示例:

>gdb -q -x restart.py ./a.out
Reading symbols from /home/a.out...done.
process id: 1700
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9         *ptr = *ptr +1;
#0  0x000000000040060e in c () at main2.cpp:9
#1  0x000000000040062a in main () at main2.cpp:15
process id: 1704
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9         *ptr = *ptr +1;
#0  0x000000000040060e in c () at main2.cpp:9
#1  0x000000000040062a in main () at main2.cpp:15
process id: 1705
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9         *ptr = *ptr +1;
#0  0x000000000040060e in c () at main2.cpp:9
#1  0x000000000040062a in main () at main2.cpp:15
process id: 1706
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9         *ptr = *ptr +1;
#0  0x000000000040060e in c () at main2.cpp:9
#1  0x000000000040062a in main () at main2.cpp:15
(gdb)

对于每次崩溃,创建了一个带有名称crash.file.pid的文件。这是文件的一个示例:

>more crash.file.1860
#0  0x000000000040060e in c () at main2.cpp:9
#1  0x000000000040062a in main () at main2.cpp:15

这是一个C 程序:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int c()
{
  printf("process id: %dn", getpid());
  int *ptr =0;
  *ptr = *ptr +1;
  return *ptr;
}
int main()
{
  c();
  return 0;
}

这是一个python脚本:

>cat restart.py
#!gdb
import sys
import gdb
import os
number_restarts = 3
def on_stop(sig):
  global number_restarts
  if isinstance(sig, gdb.SignalEvent) and sig.stop_signal == "SIGSEGV":
    crash_file = "crash.file." + str( gdb.selected_inferior().pid)
    gdb.execute("set logging file " + crash_file)
    gdb.execute("set logging on")
    gdb.execute("where")
    gdb.execute("set logging off")
    if (number_restarts > 0):
      number_restarts -= 1
      gdb.execute("set confirm off")
      gdb.execute("kill")
      gdb.execute("run")

gdb.events.stop.connect (on_stop)
gdb.execute("set pagination off")
gdb.execute("run")