Debugging 脱离Gdb而不恢复下位机

Debugging 脱离Gdb而不恢复下位机,debugging,gdb,Debugging,Gdb,Gdb和其他任何程序一样,都不是完美的,我时不时会遇到使当前Gdb实例无法使用的bug。在这一点上,如果我有一个调试会话,其中有很多有价值的状态,我希望能够在它上面启动一个新的Gdb会话。也就是说,分离、退出Gdb并启动一个新的Gdb实例,以便在我停止的地方重新启动 然而,当分离Gdb时,它会恢复下级,以便继续在原来的位置运行,这破坏了整个练习的重点。因此,我想知道是否有可能在这样一种状态下分离,即基本上,下级就好像它被发送了一个SIGSTOP 我曾经尝试过简单地杀死Gdb,但有趣的是,这似乎是

Gdb和其他任何程序一样,都不是完美的,我时不时会遇到使当前Gdb实例无法使用的bug。在这一点上,如果我有一个调试会话,其中有很多有价值的状态,我希望能够在它上面启动一个新的Gdb会话。也就是说,分离、退出Gdb并启动一个新的Gdb实例,以便在我停止的地方重新启动

然而,当分离Gdb时,它会恢复下级,以便继续在原来的位置运行,这破坏了整个练习的重点。因此,我想知道是否有可能在这样一种状态下分离,即基本上,下级就好像它被发送了一个
SIGSTOP

我曾经尝试过简单地杀死Gdb,但有趣的是,这似乎是采取了劣势。我不知道这是怎么回事

当分离Gdb时,它将恢复下位机

GDB没有,内核有(假设是Linux)

我曾经尝试过简单地杀死Gdb,但有趣的是,这似乎是采取了劣势

内核发送它
SIGHUP
,这通常会杀死下级。您可以使用下方的
SIG\u IGN
或简单的
(gdb)呼叫信号(1,1)
来防止这种情况

在那之后,您可以分离并退出GDB,但是内核将使用
SIGCONT
(参见下面的更新)恢复次进程,因此您回到了原点

然而,有一个解决办法。考虑下面的程序:

int main()
{
  while (1) {
    printf("."); fflush(0); sleep(1);
  }
}

gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out 
.....^C
Program received signal SIGINT, Interrupt.
0x00007ffff7ad5de0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
我们希望程序不会在分离时跑掉,因此我们发送它
SIGSTOP

(gdb) signal SIGSTOP
Continuing with signal SIGSTOP.

Program received signal SIGSTOP, Stopped (signal).
0x00007ffff7ad5de0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  in ../sysdeps/unix/syscall-template.S
(gdb) detach
Detaching from program: /tmp/a.out, process 25382
请注意,此时gdb已分离(但仍处于活动状态),程序未运行(已停止)

现在在另一个终端:

gdb -q -ex 'set prompt (gdb2) ' -p 25382
0x00007ffff7ad5de0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb2) c
Continuing.

Program received signal SIGSTOP, Stopped (signal).
0x00007ffff7ad5de0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  in ../sysdeps/unix/syscall-template.S
(gdb2) sig 0
Continuing with no signal.
程序继续运行,在第一个终端中打印点

更新:

SIGHUP
——很有趣。但是,通过什么机制

好问题。我不知道,但这似乎是答案:

setpgid

我已经验证过,如果我分离并退出GDB而不停止下级,它不会得到
SIGHUP
,并继续运行而不会死亡

如果我确实发送了
SIGSTOP
并安排忽略
SIGHUP
,那么我会看到
SIGHUP
SIGCONT
strace
中发送,以便与手册页完全匹配:

(gdb) detach
Detaching from program: /tmp/a.out, process 41699
在另一个窗口中:
strace-p41699
。返回GDB:

(gdb) quit
strace输出:

--- stopped by SIGSTOP ---
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
--- SIGCONT {si_signo=SIGCONT, si_code=SI_KERNEL} ---
restart_syscall(<... resuming interrupted call ...>) = 0
write(1, ".", 1.)                        = 1
...
——被SIGSTOP停止---
---SIGHUP{si_signo=SIGHUP,si_code=si_KERNEL}---
---SIGCONT{si_signo=SIGCONT,si_code=si_KERNEL}---
重新启动\u syscall()=0
写入(1,“.”,1.)=1
...

“内核发送它
SIGHUP
”——很有趣。但是,通过什么机制?我在
ptrace
manpage中找不到任何关于
SIGHUP
被发送的信息,而且下级显然没有在自己的pty中运行。哦,很有趣。我实际上不知道流程组的功能。这很好地解释了为什么我在尝试
SIGSTOP
过程时丢失了一些进程。谢谢
--- stopped by SIGSTOP ---
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
--- SIGCONT {si_signo=SIGCONT, si_code=SI_KERNEL} ---
restart_syscall(<... resuming interrupted call ...>) = 0
write(1, ".", 1.)                        = 1
...