脱离Gdb而不恢复劣势

时间:2016-09-27 20:40:56

标签: debugging gdb

与任何其他程序一样,Gdb并不完美,我偶尔会遇到使当前Gdb实例无法使用的错误。此时,如果我的调试会话中有很多有价值的状态,我希望能够在其上启动一个新的Gdb会话。也就是说,分离,退出Gdb并启动一个新的Gdb实例,以便在我离开的地方重新启动。

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

我曾经尝试过简单地杀死Gdb,但有趣的是,这似乎比较差。不确定它是如何工作的。

1 个答案:

答案 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被忽略,那么我会看到SIGCONTstrace都在(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}}