我正在调试一个多进程应用程序,
如何在fork()
出的进程之间切换?
您可以让子进程休眠,然后附加一个新的GDB实例。GDB用户手册描述了此过程如下(重点是我的):
在大多数系统上,gdb没有特殊的支持来调试使用fork函数创建其他进程的程序。当程序fork时,gdb将继续调试父进程,而子进程将不受阻碍地运行。如果您在任何子进程执行的代码中设置了断点,则子进程将收到SIGTRAP信号(除非它捕获该信号),这会导致它终止。
但是,如果要调试子进程,则有一种不太痛苦的解决方法。在子进程执行fork后的代码中放置一个sleep调用。如果设置了某个环境变量或某个文件存在,则仅在需要在子项上运行gdb时才休眠,以便无需发生延迟。当子进程正在睡眠时,使用ps程序获取其进程ID。然后告诉gdb(如果您还调试父进程,则为gdb的新调用)附加到子进程(请参见Attach)。从那时起,您可以像调试连接的任何其他进程一样调试子进程。
长话短说,当您启动稍后会fork的程序时,GDB将保持与父进程的连接(尽管您可以使用set follow-fork-mode child
来跟随子进程)。通过让另一个进程休眠,您可以让新的GDB实例也连接到它。
使用set detach-on-fork off
来控制两个进程都在gdb的控制下。默认情况下,将像往常一样调试父进程,并暂停子进程,但是通过调用set follow-fork-mode child
,您可以更改此行为(以便像通常一样调试子进程并暂停父进程)。GDB用户手册描述了此过程如下:
gdb将保留对所有forked进程(包括嵌套forks)的控制。您可以使用
info inferiors
命令列出由gdb控制的forked进程,并使用inferior
命令从一个fork切换到另一个fork(请参见Debugging Multiple Inferiors and Programs)。要退出调试其中一个forked进程,可以使用
detach inferiors
命令从中分离(使其独立运行),也可以使用kill inferiors
命令将其杀死。请参见Debugging Multiple Inferiors and Programs。
(gdb) info inferiors
Num Description Executable
1 process 1000 /tmp/a.out
* 2 <null> /tmp/a.out # current attach inferior
切换不同的进程。
(gdb) inferior 1
[Switching to inferior 1 [process 1000] (/tmp/a.out)]
[Switching to thread 1.1 (LWP 1000)]