当分离 Gdb 时,它恢复下级
GDB 不会,内核会(假设是 Linux)。
我试过简单地杀死 Gdb,但有趣的是,这似乎也带走了劣等的东西
内核发送它SIGHUP
,通常会杀死劣等人。您可以通过以下任一方法来防止这种情况发生SIG_IGN
在劣势,或者简单地说(gdb) call signal(1, 1)
.
之后,您可以分离并退出 GDB,但内核将恢复以下状态:SIGCONT
(请参阅下面的更新),所以您回到了第一个地方。
然而,有is一个办法。考虑以下程序:
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.
我们希望该程序能够not分离时逃跑,所以我们发送它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 已分离(但仍处于活动状态),并且程序正在运行not运行(停止)。
现在在不同的终端中:
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.
程序继续运行,在第一个终端中打印点。
Update:
SIGHUP
- 有趣的。但是通过什么机制呢?
好问题。我不知道,但这似乎就是答案:
From setpgid
man page http://man7.org/linux/man-pages/man2/setpgid.2.html:
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.
我已经验证,如果我分离并退出 GDB 而不停止劣等,它不会得到SIGHUP
并继续奔跑而不死。
如果我发送的话SIGSTOP
并安排SIGHUP
被忽略,然后我看到两者SIGHUP
and SIGCONT
被送入strace
,因此与手册页完全匹配:
(gdb) detach
Detaching from program: /tmp/a.out, process 41699
在另一个窗口中:strace -p 41699
。回到GDB:
(gdb) quit
跟踪输出:
--- 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
...