乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      用GDB調(diào)試多進(jìn)程程序

       楚暮四 2010-05-08

      眾所周知,GDB是Unix/Linux下調(diào)試程序的龍頭老大,GDB功能強(qiáng)大,我們?cè)谄綍r(shí)多使用其一些 最基本的功能,而且一般調(diào)試的都是單進(jìn)程的程序。最近一個(gè)項(xiàng)目中的問題讓我接觸如何使用GDB調(diào)試多進(jìn)程程序,更確切的是說調(diào)試調(diào)用fork的多進(jìn)程程 序。

      使用GDB最好的文檔就是其名為'Debugging with GDB' 的參考手冊(cè)。手冊(cè)中有一小章節(jié)提到了如何調(diào)試多進(jìn)程程序。一般情況下,如果被gdb調(diào)試的程序中調(diào)用fork派生出一個(gè)新的子進(jìn)程,這時(shí)gdb調(diào)試的仍然 還是父進(jìn)程,其子進(jìn)程的執(zhí)行不被理會(huì)。如果之前你在子進(jìn)程的執(zhí)行routine上設(shè)置了斷點(diǎn),那么當(dāng)子進(jìn)程執(zhí)行到那個(gè)斷點(diǎn)時(shí),子進(jìn)程會(huì)因?yàn)槭盏揭粋€(gè) SIGTRAP信號(hào)而自行終止,除非你在子進(jìn)程中攔截了該信號(hào)。

      那么使用GDB該如何調(diào)試多進(jìn)程程序呢?在其參考手冊(cè)中提供了一種通用方法,這里說說(GDB在某些平臺(tái)上如HP-UX,還提供了更簡便的方法,不過不具備通用性,這里不說):

      [測(cè)試程序]
      我們先看看我們的測(cè)試程序:
      /* in eg1.c */

      int wib(int no1, int no2)
      {
              int result, diff;
              diff = no1 - no2;
              result = no1 / diff;
              return result;
      }

      int main()
      {
              pid_t   pid;

              pid = fork();
              if (pid <0) {
                      printf("fork err\n");
                      exit(-1);
              } else if (pid == 0) {
                      /* in child process */
                      sleep(60); ------------------ (!)

                      int     value   = 10;
                      int     div     = 6;
                      int     total   = 0;
                      int     i       = 0;
                      int     result  = 0;

                      for (i = 0; i < 10; i++) {
                              result = wib(value, div);
                              total += result;
                              div++;
                              value--;
                      }

                      printf("%d wibed by %d equals %d\n", value, div, total);
                      exit(0);
              } else {
                      /* in parent process */
                      sleep(4);
                      wait(-1);
                      exit(0);
              }
      }
      該測(cè)試程序中子進(jìn)程運(yùn)行過程中會(huì)在wib函數(shù)中出現(xiàn)一個(gè)'除0'異?!,F(xiàn)在我們就要調(diào)試該子進(jìn)程。

      [調(diào)試原理]
      不知道大家發(fā)現(xiàn)沒有,在(!)處在我們的測(cè)試程序在父進(jìn)程fork后,子進(jìn)程調(diào)用sleep睡了60秒。這就是關(guān)鍵,這個(gè) sleep本來是不該存在于子進(jìn)程代碼中的,而是而了使用GDB調(diào)試后加入的,它是我們調(diào)試的一個(gè)關(guān)鍵點(diǎn)。為什么要讓子進(jìn)程剛剛運(yùn)行就開始sleep呢? 因?yàn)槲覀円谧舆M(jìn)程睡眠期間,利用shell命令獲取其process id,然后再利用gdb調(diào)試外部進(jìn)程的方法attach到該process id上,調(diào)試該進(jìn)程。

      [調(diào)試過程]
      我覺上面的調(diào)試原理的思路已經(jīng)很清晰了,剩下的就是如何操作的問題了。我們來實(shí)踐一次吧!
      我所使用的環(huán)境是Solaris OS 9.0/GCC 3.2/GDB 6.1。

      GDB調(diào)試程序的前提條件就是你編譯程序時(shí)必須加入調(diào)試符號(hào)信息,即使用'-g'編譯選項(xiàng)。首先編譯我們的源程序'gcc -g -o eg1 eg1.c'。編譯好之后,我們就有了我們的調(diào)試目標(biāo)eg1。由于我們?cè)谡{(diào)試過程中需要多個(gè)工具配合,所以你最好多打開幾個(gè)終端窗口,另外一點(diǎn)需要注意的 是最好在eg1的working directory下執(zhí)行g(shù)db程序,否則gdb回提示'No symbol table is loaded'。你還得手工load symbol table。好了,下面我們就'按部就班'的開始調(diào)試我們的eg1。

      執(zhí)行eg1:
      eg1 &   --- 讓eg1后臺(tái)運(yùn)行吧。

      查找進(jìn)程id:
      ps -fu YOUR_USER_NAME

      運(yùn)行g(shù)db:
      gdb
      (gdb) attach xxxxx  --- xxxxx為利用ps命令獲得的子進(jìn)程process id
      (gdb) stop --- 這點(diǎn)很重要,你需要先暫停那個(gè)子進(jìn)程,然后設(shè)置一些斷點(diǎn)和一些Watch
      (gdb) break 37 -- 在result = wib(value, div);這行設(shè)置一個(gè)斷點(diǎn),可以使用list命令察看源代碼
      Breakpoint 1 at 0x10808: file eg1.c, line 37.
      (gdb) continue
      Continuing.

      Breakpoint 1, main () at eg1.c:37
      37                              result = wib(value, div);
      (gdb) step
      wib (no1=10, no2=6) at eg1.c:13
      13              diff = no1 - no2;
      (gdb) continue
      Continuing.

      Breakpoint 1, main () at eg1.c:37
      37                              result = wib(value, div);
      (gdb) step
      wib (no1=9, no2=7) at eg1.c:13
      13              diff = no1 - no2;
      (gdb) continue
      Continuing.

      Breakpoint 1, main () at eg1.c:37
      37                              result = wib(value, div);
      (gdb) step
      wib (no1=8, no2=8) at eg1.c:13
      13              diff = no1 - no2;
      (gdb) next
      14              result = no1 / diff;
      (gdb) print diff
      $6 = 0        ------- 除數(shù)為0,我們找到罪魁禍?zhǔn)琢恕?br>(gdb) next
      Program received signal SIGFPE, Arithmetic exception.
      0xff29d830 in .div () from /usr/lib/libc.so.1

      至此,我們調(diào)試完畢。

      上面僅僅是一個(gè)簡單的多進(jìn)程程序,在我們平時(shí)開發(fā)的多進(jìn)程程序遠(yuǎn)遠(yuǎn)比這個(gè)復(fù)雜,但是調(diào)試基本原理是不變,有一些技巧則需要我們?cè)趯?shí)踐中慢慢摸索。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多