GDB调试多进程的fork+exec

通过一个实例来观察协同进程,在程序中创建了两个管道, 父、子进程各自关闭它们不需要使用的端口。
两个管道一个用作协同进程的标准输入,另一个用作它的标准输出、子进程在调用dup2后使管道描述符移至其标准输入和标准输出, 然后调用execl。
 
#include <apue.h>

int main(void)
{
	int 	n, int1, int2;
	char	line[MAXLINE];

	while((n = read(STDIN_FILENO, line, MAXLINE)) > 0)
	{
		line[n] = 0;	/*null terminate*/
		if(sscanf(line, "%d%d", &int1, &int2) == 2)
		{	
			sprintf(line, "%d\n", int1 + int2);
			n = strlen(line);
			if(write(STDOUT_FILENO, line, n) != n)
				err_sys("write error");
		}
	
		else
		{
			if(write(STDOUT_FILENO,"invalid args\n", 13) != 13)
				err_sys("write error");
		}
	}
	
	exit(0);

}
#include <apue.h>

static void sig_pipe(int);		/*our signal handler*/

int main(void)
{
	int 	n, fd1[2], fd2[2];
	pid_t 	pid;
	char	line[MAXLINE];

	if(signal(SIGPIPE, sig_pipe) == SIG_ERR)
		err_sys("signal error");

	if(pipe(fd1) < 0 || pipe(fd2) < 0)
		err_sys("pipe error");

	if((pid = fork()) < 0)
	{
		err_sys("fork error");
	}
	else if(pid > 0)			//parent
	{
		close(fd1[0]);
		close(fd2[1]);
		while(fgets(line, MAXLINE, stdin) != NULL)
		{
			n = strlen(line);
			if(write(fd1[1], line, n) != n)
				err_sys("write error to pipe");
			if((n = read(fd2[0], line, MAXLINE)) < 0)
				err_sys("read error from pipe");
			if(n == 0)
			{
				err_msg("child closed pipe");
				break;
			}
			line[n] = 0;	/*null terminate*/
			if(fputs(line, stdout) == EOF)
				err_sys("fputs error");
		}

		if(ferror(stdin))
			err_sys("fgets error on stdin");
		exit(0);
	}
	else					//child
	{
		close(fd1[1]);
		close(fd2[0]);
		if(fd1[0] != STDIN_FILENO)
		{
			if(dup2(fd1[0],STDIN_FILENO) != STDIN_FILENO)
				err_sys("dup2 error to stdin");
			close(fd1[0]);
		}

		if(fd2[1] != STDOUT_FILENO)
		{
			if(dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO)
				err_sys("dup2 error to stdout");
			close(fd2[1]);
		}
		
		if(execl("./add2", "add2", (char *)0) < 0)
			err_sys("execl error");

	}

	exit(0);
}

static void sig_pipe(int signo)
{
	printf("SIGPIPE caught\n");
	exit(1);
}


[root@localhost fig15]# gdb a.out 
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /mnt/hgfs/centos/apue.2e/fig15/a.out...done.
(gdb) b 17
Breakpoint 1 at 0x8048857: file 15-9.c, line 17.
(gdb) b 50
Breakpoint 2 at 0x80489ed: file 15-9.c, line 50.
(gdb) catch exec 
Catchpoint 3 (exec)
(gdb) show follow-fork-mode
Debugger response to a program call of fork or vfork is "parent".
(gdb) set detach-on-fork off
(gdb) run
Starting program: /mnt/hgfs/centos/apue.2e/fig15/a.out 


Breakpoint 1, main () at 15-9.c:17
17 if((pid = fork()) < 0)
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.i686
(gdb) n
[New process 7275]
21 else if(pid > 0) //parent
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.i686
(gdb) n
23 close(fd1[0]);
(gdb) n
24 close(fd2[1]);
(gdb) n
25 while(fgets(line, MAXLINE, stdin) != NULL)
(gdb) n
333 666
27 n = strlen(line);
(gdb) n
28 if(write(fd1[1], line, n) != n)
(gdb) n
30 if((n = read(fd2[0], line, MAXLINE)) < 0)
(gdb) info inferiors 
  Num  Description       Executable        
  2    process 7275      /mnt/hgfs/centos/apue.2e/fig15/a.out 
* 1    process 7272      /mnt/hgfs/centos/apue.2e/fig15/a.out 
(gdb) inferior 2
[Switching to inferior 2 [process 7275] (/mnt/hgfs/centos/apue.2e/fig15/a.out)]
[Switching to thread 2 (process 7275)] 
#0  0x00110424 in ?? ()
(gdb) bt
#0  0x00110424 in ?? ()
#1  0x0804885c in main () at 15-9.c:17
(gdb) c
Continuing.


Breakpoint 2, main () at 15-9.c:50
50 if(fd1[0] != STDIN_FILENO)
(gdb) bt
#0  main () at 15-9.c:50
(gdb) c
Continuing.
process 7275 is executing new program: /mnt/hgfs/centos/apue.2e/fig15/add2


Catchpoint 3 (exec'd /mnt/hgfs/centos/apue.2e/fig15/add2), 0x00be3850 in _start
    () from /lib/ld-linux.so.2
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.i686
(gdb) l
1 #include <apue.h>
2
3 int main(void)
4 {
5 int n, int1, int2;
6 char line[MAXLINE];
7
8 while((n = read(STDIN_FILENO, line, MAXLINE)) > 0)
9 {
10 line[n] = 0; /*null terminate*/
(gdb) b 8
Breakpoint 4 at 0x80486c0: file 15-8.c, line 8.
(gdb) c
Continuing.


Breakpoint 4, main () at 15-8.c:8
8 while((n = read(STDIN_FILENO, line, MAXLINE)) > 0)
(gdb) c
Continuing.
^Z
Program received signal SIGTSTP, Stopped (user).
0x00110424 in ?? ()
(gdb) inferior 1
[Switching to inferior 1 [process 7272] (/mnt/hgfs/centos/apue.2e/fig15/a.out)]
[Switching to thread 1 (process 7272)] 
#0  main () at 15-9.c:30
30 if((n = read(fd2[0], line, MAXLINE)) < 0)
(gdb) n


Program received signal SIGTSTP, Stopped (user).
main () at 15-9.c:30
30 if((n = read(fd2[0], line, MAXLINE)) < 0)
(gdb) n


Program received signal SIGTSTP, Stopped (user).
main () at 15-9.c:30
30 if((n = read(fd2[0], line, MAXLINE)) < 0)
(gdb) n


Program received signal SIGTSTP, Stopped (user).
main () at 15-9.c:30
30 if((n = read(fd2[0], line, MAXLINE)) < 0)
(gdb) n
32 if(n == 0)
(gdb) n
37 line[n] = 0; /*null terminate*/
(gdb) n
38 if(fputs(line, stdout) == EOF)
(gdb) n
999
25 while(fgets(line, MAXLINE, stdin) != NULL)
(gdb) 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值