与任何其他程序一样,Gdb并不完美,我偶尔会遇到使当前Gdb实例无法使用的错误。此时,如果我的调试会话中有很多有价值的状态,我希望能够在其上启动一个新的Gdb会话。也就是说,分离,退出Gdb并启动一个新的Gdb实例,以便在我离开的地方重新启动。
然而,当分离Gdb时,它恢复了下级,以便它继续在原地运行,这破坏了整个练习的重点。因此,我想知道是否有可能在这样的状态下分离,以至于劣等就好像它已被发送SIGSTOP
,基本上。
我曾经尝试过简单地杀死Gdb,但有趣的是,这似乎比较差。不确定它是如何工作的。
答案 0 :(得分:2)
分离Gdb时,它会恢复下级
GDB没有,内核会这样做(假设是Linux)。
我尝试过简单地杀死Gdb,但有趣的是,这似乎比较低劣了
内核发送它SIGHUP
,通常会杀死下级。您可以使用下级SIG_IGN
或(gdb) call signal(1, 1)
中的SIGCONT
来阻止这种情况。
之后,您可以分离并退出GDB,但内核将使用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 -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.
请注意,此时,gdb已分离(但仍处于活动状态),程序未正在运行(已停止)。
现在在另一个终端:
SIGHUP
程序继续运行,在第一个终端打印点。
<强>更新强>
setpgid
- 有趣。但是通过什么机制?
好问题。我不知道,但这似乎是答案:
来自If the exit of the process causes a process group to become orphaned,
and if any member of the newly orphaned process group is stopped,
then a SIGHUP signal followed by a SIGCONT signal will be sent to
each process in the newly orphaned process group.
man page:
SIGHUP
我已经确认,如果我在不停止劣势的情况下分离和退出GDB,它就不会获得SIGSTOP
并继续运行而不会死亡。
如果我发送SIGHUP
并安排SIGHUP
被忽略,那么我会看到SIGCONT
和strace
都在(gdb) detach
Detaching from program: /tmp/a.out, process 41699
中发送,所以与手册页完全匹配:
strace -p 41699
在另一个窗口中:(gdb) quit
。回到GDB:
--- 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
...
strace输出:
{{1}}