转自:http://blog.csdn.net/chn89/article/details/7098823
这位IBMer提出三种调试方式,很是靠谱。http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/。鉴于本人的嵌入式背景,多数不太适合采用VNC,于是乎,就举例说明前两种方法吧。待调试代码
- 1 #include <stdlib.h>
- 2 #include <unistd.h>
- 3
- 4 int main(){
- 5 pid_t pid;
- 6 int status , i = 9;
- 7
- 8 printf("Now going to fork\n");
- 9
- 10 pid = fork();
- 11 if(pid<0){
- 12 printf("fork error\n");
- 13 return -1;
- 14 }
- 15 else if( pid>0 ){
- 16 wait(&status);
- 17 printf("return %d\n",WEXITSTATUS(status));
- 18 exit(0);
- 19 }
- 20 else {
- 21 while(i-->0){
- 22 printf("loop %d\n",i);
- 23 sleep(2);
- 24 }
- 25 exit(3);
- 26 }
- 27
- 28
- 29 }
方法1:
编译 gcc -g multi_proc.c
加载 gdb a.out
- (gdb) set follow-fork-mode child
- (gdb) b 23
- (gdb) r
- Starting program: /home/XXX/test/a.out
- Now going to fork
- [New process 30427]
- [Switching to process 30427]
- Breakpoint 1, main () at multi_proc.c:22
- 22 printf("loop %d\n",i);
- Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.i686
- (gdb) c
- Continuing.
- loop 8
于是就可以正常调试子进程了。
方法2 :
对于方案1,如果进程继承级别比较多,调试起来比较麻烦,而且还限定了GDB必须为高版本。当然现在的GDB版本都是满足的。方案2的精髓就是attach子进程,如果需要让子进程在被attach之前不做任何操作,可以采用条件触发的方法。其中一个方案可以采用下文。
- while(1){
- if(file exist){
- some thing realy do;
- break;
- }
- else{
- sleep(1);
- }
- }
在attach进程之后,touch file,进程才真正执行。
调试步骤,打开一个console
- [XXX@localhost test]$ ./a.out
- Now going to fork
- child pid = 31803
再打开一个cnsole
- gdb a.out 31803
- (gdb) bt
- #0 0x00544416 in __kernel_vsyscall ()
- #1 0x00bf1060 in __nanosleep_nocancel () from /lib/libc.so.6
- #2 0x00bf0ea4 in sleep () from /lib/libc.so.6
- #3 0x08048563 in main () at multi_proc.c:23
- (gdb) l 23
- 19 exit(0);
- 20 }
- 21 else {
- 22 while(i-->0){
- 23 printf("loop %d\n",i);
- 24 sleep(4);
- 25 }
- 26 exit(3);
- 27 }
- 28
- (gdb)
结合bt命令和第24行的源代码,说明进程睡在这里呢