歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> linux 下用gdb單步調試多進程

linux 下用gdb單步調試多進程

日期:2017/3/3 12:46:54   编辑:Linux技術
轉自:http://www.linuxidc.com/Linux/2011-04/34838p5.htm
當你在程序中使用fork(),如果用gdb來調試.不管是你在子進程是否設置斷點.你都只能在父進程單步調試,而沒辦法進入到子進程當中進行單步調試.因為gdb的所有處理(查看堆棧,內存,變量值)都是針對當前進程空間.
那麼是否就沒辦法調試多進程程序的子進程代碼呢?辦法還是有的,一般的標准方法是再打開一個gdb用attach功能來調試子進程.gdbattach功能是不執行被調試程序,而是把gdb“掛”到一個已經運行的進程之上來進行調試,這掛載的動作稱為attach.當然也包括掛載子進程。
首先我們看一個如下簡單的多進程程序。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define PRINT_INT(e) printf("%s=%d\n",#e,e)
int main()
{
pid_t pid;
int i,val = 100;
printf("process id %d\n",getpid());
pid = fork();
PRINT_INT(val);
if(pid == 0)
{
val+=100;
printf("child process id %d,parent id%d\n",getpid(),getppid());
PRINT_INT(val);
i = 0;
while(1)
{
printf("child [%d]\n",i++);
sleep(1);
}
}
else if(pid >0)
{
printf("parent process id %d\n",getpid());
for(i=0 ; i< 5 ; i++)
{
printf("parent [%d]\n",i);
}
val+=10;
PRINT_INT(val);
wait(NULL);
}
else
{
exit(-1);
}
PRINT_INT(val);
return 0;
}
這個程序很簡單,就是子進程在無限循環打印屏幕,而父進程在用wait等待.
編譯 gcc test_fork.c -o test_fork -g
1.雙gdb調試
首先用常規方法gdb test_fork.c調試程序,分別在31行,41行設斷點,然後用run執行程序,可以看到gdb在41行父進程的斷點停下來.但是子進程在自行執行,無法在31斷點停下.
這時用gdb attach功能來調試子進程,首先用ps -aux | grep test_fork找出子進程號.
然後用 gdb test_fork<進程號>掛入已經知進程.這時就可以看到在子進程的斷點可以停下來,而且父進程的gdb窗口裡,子進程輸出停下並受子進程的gdb控制,這裡你可以用常規調試手段來看程序了.(如看memory,watch,stack等)

操作步驟,進入gdb首先用b 31設置子進程中斷點.然後用c(這裡要用continue,因為attach的進程已經在運行了,不能用run)
然後可以看到斷點在生效了.至此可以常規調試方法即可
[root@localhost src]# ps -aux | grep test_fork
Warning: bad syntax, perhaps a bogus '-'? See/usr/share/doc/procps-3.2.7/FAQ
root 3957 0.0 0.2 11012 4824pts/7 S+ 13:18 0:00 gdb test_fork
root 3959 0.0 0.0 1516 328pts/7 T 13:19 0:00/home/hxy/src/test_fork
root 3962 0.0 0.0 1516 280pts/7 S 13:19 0:00/home/hxy/src/test_fork
root 3985 0.0 0.0 5020 672pts/9 R+ 13:19 0:00 grep test_fork
[root@localhost src]# gdb test_fork 3962
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
(gdb) b 31
Breakpoint 1 at 0x8048541: file test_fork.c, line 31.
(gdb) c
Continuing.

Breakpoint 1, main () at test_fork.c:31
31 printf("child [%d]\n",i++);
(gdb) n
32 sleep(1);
(gdb) n
33 }
(gdb)

2.圖形界面kdbg的調試
命令行界面gdb還是太麻煩了,一般我們還是采用界面前端來進行調試程序,一般用KDE自帶KDbg最為方便.
2.1 首先用一個Kdbg打開程序
在圖形界面設置斷點,然後運行,可以看到主程序的斷點已經進入並停下來了.


2.2再打開一個kdbg,並且打開test_fork,設置好子進程的斷點,選擇主菜單的Execution->Attach,這時會出現如下界面,從進程列表選擇子進程或用ps查到子進程ID直接輸入即可

2.3 此時兩個kdbg在同時調一個程序不同進程,注意所有標准輸入輸出都發生在調試主進程的kdbg的終端窗口裡
Copyright © Linux教程網 All Rights Reserved