欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Linux gdb調(diào)試器用法全面解析

系統(tǒng) 1996 0

GDB是GNU開(kāi)源組織發(fā)布的一個(gè)強(qiáng)大的UNIX下的程序調(diào)試工具,GDB主要可幫助工程師完成下面4個(gè)方面的功能:

  • 啟動(dòng)程序,可以按照工程師自定義的要求隨心所欲的運(yùn)行程序。
  • 讓被調(diào)試的程序在工程師指定的斷點(diǎn)處停住,斷點(diǎn)可以是條件表達(dá)式。
  • 當(dāng)程序被停住時(shí),可以檢查此時(shí)程序中所發(fā)生的事,并追索上文。
  • 動(dòng)態(tài)地改變程序的執(zhí)行環(huán)境。

不管是調(diào)試Linux內(nèi)核空間的驅(qū)動(dòng)還是調(diào)試用戶空間的應(yīng)用程序,掌握gdb的用法都是必須。而且,調(diào)試內(nèi)核和調(diào)試應(yīng)用程序時(shí)使用的gdb命令是完全相同的,下面以代碼清單22.2的應(yīng)用程序?yàn)槔菔緂db調(diào)試器的用法。

            
              1
            
            
              int
            
             add(
            
              int
            
             a, 
            
              int
            
            
               b)


            
            
              2
            
            
                {


            
            
              3
            
            
              return
            
             a +
            
               b;


            
            
              4
            
            
                }


            
            
              5
            
            
              6
            
            
                main()


            
            
              7
            
            
                {


            
            
              8
            
            
              int
            
             sum[
            
              10
            
            ] = 


            
              9
            
            
                  {


            
            
              10
            
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            , 
            
              0
            
            
              11
            
            
                 }  ;


            
            
              12
            
            
              int
            
            
               i;


            
            
              13
            
            
              14
            
            
              int
            
             array1[
            
              10
            
            ] =


            
              15
            
            
                 {


            
            
              16
            
            
              48
            
            , 
            
              56
            
            , 
            
              77
            
            , 
            
              33
            
            , 
            
              33
            
            , 
            
              11
            
            , 
            
              226
            
            , 
            
              544
            
            , 
            
              78
            
            , 
            
              90
            
            
              17
            
            
                 };


            
            
              18
            
            
              int
            
             array2[
            
              10
            
            ] =


            
              19
            
            
                 {


            
            
              20
            
            
              85
            
            , 
            
              99
            
            , 
            
              66
            
            , 
            
              0x199
            
            , 
            
              393
            
            , 
            
              11
            
            , 
            
              1
            
            , 
            
              2
            
            , 
            
              3
            
            , 
            
              4
            
            
              21
            
            
                 };


            
            
              22
            
            
              23
            
            
              for
            
             (i = 
            
              0
            
            ; i < 
            
              10
            
            ; i++
            
              )


            
            
              24
            
            
                 {


            
            
              25
            
                 sum[i] =
            
               add(array1[i], array2[i]);


            
            
              26
            
            
                 }


            
            
              27
            
             }
          

使用命令gcc –g gdb_example.c –o gdb_example編譯上述程序,得到包含調(diào)試信息的二進(jìn)制文件example,執(zhí)行g(shù)db gdb_example命令進(jìn)入調(diào)試狀態(tài):

      
        [root@localhost driver_study]# gdb gdb_example

GNU gdb Red Hat Linux (
      
      
        5
      
      .3post-
      
        0.20021129
      
      
        .18rh)

Copyright 
      
      
        2003
      
      
         Free Software Foundation, Inc.

GDB is 
      
      
        free
      
      
         software, covered by the GNU General Public License, and you are

welcome to change it and
      
      /
      
        or distribute copies of it under certain conditions.

Type 
      
      
        "
      
      
        show copying
      
      
        "
      
      
         to see the conditions.

There is absolutely no warranty 
      
      
        for
      
       GDB.  Type 
      
        "
      
      
        show warranty
      
      
        "
      
      
        for
      
      
         details.

This GDB was configured as 
      
      
        "
      
      
        i386-redhat-linux-gnu
      
      
        "
      
      
        ...

(gdb)
      
    

1、list命令

在gdb中運(yùn)行l(wèi)ist命令(縮寫(xiě)l)可以列出代碼,list的具體形式包括:

list <linenum>   顯示程序第linenum行周?chē)脑闯绦颍纾?

      (gdb) list 
      
        15
      
      
        10
      
      
        11
      
      
        int
      
       array1[
      
        10
      
      ] =


      
        12
      
      
                {


      
      
        13
      
      
        48
      
      , 
      
        56
      
      , 
      
        77
      
      , 
      
        33
      
      , 
      
        33
      
      , 
      
        11
      
      , 
      
        226
      
      , 
      
        544
      
      , 
      
        78
      
      , 
      
        90
      
      
        14
      
      
                };


      
      
        15
      
      
        int
      
       array2[
      
        10
      
      ] =


      
        16
      
      
                {


      
      
        17
      
      
        85
      
      , 
      
        99
      
      , 
      
        66
      
      , 
      
        0x199
      
      , 
      
        393
      
      , 
      
        11
      
      , 
      
        1
      
      , 
      
        2
      
      , 
      
        3
      
      , 
      
        4
      
      
        18
      
      
                };


      
      
        19
      
    

list <function>   顯示函數(shù)名為function的函數(shù)的源程序,如:

        
          (gdb) list main


        
        
          2
        
        
                 {


        
        
          3
        
                 return a +
        
           b;


        
        
          4
        
        
                 }


        
        
          5
        
        
          6
        
        
                 main()


        
        
          7
        
        
                 {


        
        
          8
        
        
          int
        
        
          sum
        
        [
        
          10
        
        
          ];


        
        
          9
        
        
          int
        
        
           i;


        
        
          10
        
        
          11
        
        
          int
        
         array1[
        
          10
        
        ] =
      

list    顯示當(dāng)前行后面的源程序。

list -   顯示當(dāng)前行前面的源程序。

下面演示了使用gdb中的run(縮寫(xiě)r)、break(縮寫(xiě)b)、next(縮寫(xiě)n)命令控制程序的運(yùn)行,并使用print(縮寫(xiě)p)命令打印程序中的變量sum的過(guò)程:

      
        (gdb) break add

Breakpoint 
      
      
        1
      
       at 
      
        0x80482f7
      
      : 
      
        file
      
       gdb_example.c, line 
      
        3
      
      
        .

(gdb) run  

Starting program: 
      
      /driver_study/
      
        gdb_example 



Breakpoint 
      
      
        1
      
      , add (a=
      
        48
      
      , b=
      
        85
      
      ) at gdb_example.c:
      
        3
      
      
        

warning: Source 
      
      
        file
      
       is 
      
        more
      
      
         recent than executable.




      
      
        3
      
               return a +
      
         b;

(gdb) next


      
      
        4
      
      
               }

(gdb) next

main () at gdb_example.c:
      
      
        23
      
      
        23
      
      
        for
      
       (i = 
      
        0
      
      ; i < 
      
        10
      
      ; i++
      
        )

(gdb) next


      
      
        25
      
      
        sum
      
      [i] =
      
         add(array1[i], array2[i]);

(gdb) print 
      
      
        sum
      
      
        

$
      
      
        1
      
       = {
      
        133
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      , 
      
        0
      
      }
    

2、run命令

在gdb中,運(yùn)行程序使用run命令。在程序運(yùn)行前,我們可以設(shè)置如下4方面的工作環(huán)境:

程序運(yùn)行參數(shù)

set args 可指定運(yùn)行時(shí)參數(shù),如: set args 10 20 30 40 50;

show args 命令可以查看設(shè)置好的運(yùn)行參數(shù)。

運(yùn)行環(huán)境

path <dir> 可設(shè)定程序的運(yùn)行路徑;

how paths 可查看程序的運(yùn)行路徑;

set environment varname [=value] 用于設(shè)置環(huán)境變量,如 set env USER=baohua;

show environment [varname] 則用于查看環(huán)境變量。

工作目錄

cd <dir> 相當(dāng)于shell的cd命令;

pwd 顯示當(dāng)前所在的目錄。

程序的輸入輸出

info terminal 用于顯示程序用到的終端的模式;

  gdb中也可以使用重定向控制程序輸出,如 run > outfile

tty 命令可以指定輸入輸出的終端設(shè)備,如: tty /dev/ttyS1

3、break命令

在gdb中用break命令來(lái)設(shè)置斷點(diǎn),設(shè)置斷點(diǎn)的方法包括:

break <function>

  在進(jìn)入指定函數(shù)時(shí)停住,C++中可以使用class::function或function(type, type)格式來(lái)指定函數(shù)名。

break <linenum>

  在指定行號(hào)停住。

break +offset / break -offset

  在當(dāng)前行號(hào)的前面或后面的offset行停住,offiset為自然數(shù)。

break filename:linenum

  在源文件filename的linenum行處停住。

break filename:function

  在源文件filename的function函數(shù)的入口處停住。

break *address

  在程序運(yùn)行的內(nèi)存地址處停住。

break

  break命令沒(méi)有參數(shù)時(shí),表示在下一條指令處停住。

break ... if <condition>

  “...”可以是上述的 break <linenum> break +offset / break –offset 中的參數(shù),condition表示條件,在條件成立時(shí)停住。比如在循環(huán)體中,可以設(shè)置break if i=100,表示當(dāng)i為100時(shí)停住程序。

info

  查看斷點(diǎn)時(shí),可使用info命令,如 info breakpoints [n] info break [n] (n表示斷點(diǎn)號(hào))。

4、單步命令

在調(diào)試過(guò)程中,next命令用于單步執(zhí)行,類(lèi)似VC++中的step over。next的單步不會(huì)進(jìn)入函數(shù)的內(nèi)部,與next對(duì)應(yīng)的step(縮寫(xiě)s)命令則在單步執(zhí)行一個(gè)函數(shù)時(shí),會(huì)進(jìn)入其內(nèi)部,類(lèi)似VC++中的step into。下面演示了step命令的執(zhí)行情況,在23行的add()函數(shù)調(diào)用處執(zhí)行step會(huì)進(jìn)入其內(nèi)部的“return a+b;”語(yǔ)句:

        (gdb) break 
        
          25
        
        
          

Breakpoint 
        
        
          1
        
         at 
        
          0x8048362
        
        : 
        
          file
        
         gdb_example.c, line 
        
          25
        
        
          .

(gdb) run

Starting program: 
        
        /driver_study/
        
          gdb_example 



Breakpoint 
        
        
          1
        
        , main () at gdb_example.c:
        
          25
        
        
          25
        
        
          sum
        
        [i] =
        
           add(array1[i], array2[i]);

(gdb) step

add (a
        
        =
        
          48
        
        , b=
        
          85
        
        ) at gdb_example.c:
        
          3
        
        
          3
        
                 return a + b;
      

單步執(zhí)行的更復(fù)雜用法包括:

step <count>

  單步跟蹤,如果有函數(shù)調(diào)用,則進(jìn)入該函數(shù)(進(jìn)入函數(shù)的前提是,此函數(shù)被編譯有debug信息)。step后面不加count表示一條條地執(zhí)行,加表示執(zhí)行后面的count條指令,然后再停住。

next <count>

  單步跟蹤,如果有函數(shù)調(diào)用,它不會(huì)進(jìn)入該函數(shù)。同樣地,next后面不加count表示一條條地執(zhí)行,加表示執(zhí)行后面的count條指令,然后再停住。

set step-mode

  set step-mode on用于打開(kāi)step-mode模式,這樣,在進(jìn)行單步跟蹤時(shí),程序不會(huì)因?yàn)闆](méi)有debug信息而不停住,這個(gè)參數(shù)的設(shè)置可便于查看機(jī)器碼。set step-mod off用于關(guān)閉step-mode模式。

finish

  運(yùn)行程序,直到當(dāng)前函數(shù)完成返回,并打印函數(shù)返回時(shí)的堆棧地址和返回值及參數(shù)值等信息。

until (縮寫(xiě)u)

  一直在循環(huán)體內(nèi)執(zhí)行單步,退不出來(lái)是一件令人煩惱的事情,until命令可以運(yùn)行程序直到退出循環(huán)體。

stepi(縮寫(xiě)si)和nexti(縮寫(xiě)ni)

  stepi和nexti用于單步跟蹤一條機(jī)器指令,一條程序代碼有可能由數(shù)條機(jī)器指令完成,stepi和nexti可以單步執(zhí)行機(jī)器指令。 另外,運(yùn)行“display/i $pc”命令后,單步跟蹤會(huì)在打出程序代碼的同時(shí)打出機(jī)器指令,即匯編代碼。

5、continue命令

當(dāng)程序被停住后,可以使用continue命令(縮寫(xiě)c,fg命令同continue命令)恢復(fù)程序的運(yùn)行直到程序結(jié)束,或到達(dá)下一個(gè)斷點(diǎn),命令格式為:

        continue [ignore-
        
          count]

c [ignore
        
        -
        
          count]

fg [ignore
        
        -count]
      

ignore-count表示忽略其后多少次斷點(diǎn)。 假設(shè)我們?cè)O(shè)置了函數(shù)斷點(diǎn) add() ,并 watch i ,則在continue過(guò)程中,每次遇到 add() 函數(shù)或i發(fā)生變化,程序就會(huì)停住,如:

        
          (gdb) continue

Continuing.

Hardware watchpoint 
        
        
          3
        
        
          : i



Old value 
        
        = 
        
          2
        
        
          

New value 
        
        = 
        
          3
        
        
          0x0804838d
        
        
          in
        
         main () at gdb_example.c:
        
          23
        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++
        
          )

(gdb) continue

Continuing.



Breakpoint 
        
        
          1
        
        , main () at gdb_example.c:
        
          25
        
        
          25
        
        
          sum
        
        [i] =
        
           add(array1[i], array2[i]);

(gdb) continue

Continuing.

Hardware watchpoint 
        
        
          3
        
        
          : i



Old value 
        
        = 
        
          3
        
        
          

New value 
        
        = 
        
          4
        
        
          0x0804838d
        
        
          in
        
         main () at gdb_example.c:
        
          23
        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++)
      

6、print命令

在調(diào)試程序時(shí),當(dāng)程序被停住時(shí),可以使用print命令(縮寫(xiě)為p),或是同義命令inspect來(lái)查看當(dāng)前程序的運(yùn)行數(shù)據(jù)。print命令的格式是:

         print <
        
          expr
        
        >
        
          

 print 
        
        /<f> <
        
          expr
        
        >
      

<expr> 是表達(dá)式,是被調(diào)試的程序中的表達(dá)式,

<f> 是輸出的格式,比如,如果要把表達(dá)式按16進(jìn)制的格式輸出,那么就是 /x 。在表達(dá)式中,有幾種GDB所支持的操作符,它們可以用在任何一種語(yǔ)言中, “@” 是一個(gè)和數(shù)組有關(guān)的操作符, “::” 指定一個(gè)在文件或是函數(shù)中的變量, “{<type>} <addr>” 表示一個(gè)指向內(nèi)存地址 <addr> 的類(lèi)型為type的一個(gè)對(duì)象。

下面演示了查看 sum[] 數(shù)組的值的過(guò)程:

            (gdb) print 
        
          sum
        
        
            

    $
        
        
          2
        
         = {
        
          133
        
        , 
        
          155
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        
          }  

    (gdb) next  

      

    Breakpoint 
        
        
          1
        
        , main () at gdb_example.c:
        
          25
        
        
          25
        
        
          sum
        
        [i] =
        
           add(array1[i], array2[i]);  

    (gdb) next  

    
        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++
        
          )  

    (gdb) print 
        
        
          sum
        
        
            

    $
        
        
          3
        
         = {
        
          133
        
        , 
        
          155
        
        , 
        
          143
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        , 
        
          0
        
        }  
      

當(dāng)需要查看一段連續(xù)內(nèi)存空間的值的時(shí)間,可以使用GDB的 “@” 操作符, “@” 的左邊是第一個(gè)內(nèi)存地址, “@” 的右邊則是想查看內(nèi)存的長(zhǎng)度。例如如下動(dòng)態(tài)申請(qǐng)的內(nèi)存:

      
        int
      
       *array = (
      
        int
      
       *) malloc (len * sizeof (
      
        int
      
      ));
    

在GDB調(diào)試過(guò)程中這樣顯示出這個(gè)動(dòng)態(tài)數(shù)組的值:

      p *array@len
    

print的輸出格式包括:

  • x 按十六進(jìn)制格式顯示變量。
  • d 按十進(jìn)制格式顯示變量。
  • u 按十六進(jìn)制格式顯示無(wú)符號(hào)整型。
  • o 按八進(jìn)制格式顯示變量。
  • t 按二進(jìn)制格式顯示變量。
  • a 按十六進(jìn)制格式顯示變量。
  • c 按字符格式顯示變量。
  • f 按浮點(diǎn)數(shù)格式顯示變量。

我們可用display命令設(shè)置一些自動(dòng)顯示的變量,當(dāng)程序停住時(shí),或是單步跟蹤時(shí),這些變量會(huì)自動(dòng)顯示。 如果要修改變量,如x的值,可使用如下命令:

      print x=
      
        4
      
    

當(dāng)用GDB的print查看程序運(yùn)行時(shí)的數(shù)據(jù)時(shí),每一個(gè)print都會(huì)被GDB記錄下來(lái)。GDB會(huì)以 $1,$2,$3 … 這樣的方式為每一個(gè)print命令編號(hào)。我們可以使用這個(gè)編號(hào)訪問(wèn)以前的表達(dá)式,如 $1

7、watch命令

watch一般來(lái)觀察某個(gè)表達(dá)式(變量也是一種表達(dá)式)的值是否有變化了,如果有變化,馬上停住程序。

我們有下面的幾種方法來(lái)設(shè)置觀察點(diǎn):

watch <expr> :為表達(dá)式(變量)expr設(shè)置一個(gè)觀察點(diǎn)。一旦表達(dá)式值有變化時(shí),馬上停住程序。

rwatch <expr> :當(dāng)表達(dá)式(變量)expr被讀時(shí),停住程序。

awatch <expr> :當(dāng)表達(dá)式(變量)的值被讀或被寫(xiě)時(shí),停住程序。

info watchpoints :列出當(dāng)前所設(shè)置了的所有觀察點(diǎn)。 下面演示了觀察i并在連續(xù)運(yùn)行next時(shí)一旦發(fā)現(xiàn)i變化,i值就會(huì)顯示出來(lái)的過(guò)程:

        
          (gdb) watch i

Hardware watchpoint 
        
        
          3
        
        
          : i

(gdb) next


        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++
        
          )

(gdb) next

Hardware watchpoint 
        
        
          3
        
        
          : i



Old value 
        
        = 
        
          0
        
        
          

New value 
        
        = 
        
          1
        
        
          0x0804838d
        
        
          in
        
         main () at gdb_example.c:
        
          23
        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++
        
          )

(gdb) next



Breakpoint 
        
        
          1
        
        , main () at gdb_example.c:
        
          25
        
        
          25
        
        
          sum
        
        [i] =
        
           add(array1[i], array2[i]);

(gdb) next


        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++
        
          )

(gdb) next

Hardware watchpoint 
        
        
          3
        
        
          : i



Old value 
        
        = 
        
          1
        
        
          

New value 
        
        = 
        
          2
        
        
          0x0804838d
        
        
          in
        
         main () at gdb_example.c:
        
          23
        
        
          23
        
        
          for
        
         (i = 
        
          0
        
        ; i < 
        
          10
        
        ; i++)
      

8、examine命令

我們可以使用examine命令(縮寫(xiě)為x)來(lái)查看內(nèi)存地址中的值。examine命令的語(yǔ)法如下所示:

      x/<n/f/u> <addr>
    

<addr> 表示一個(gè)內(nèi)存地址。 “x/” 后的n、f、u都是可選的參數(shù),n 是一個(gè)正整數(shù),表示顯示內(nèi)存的長(zhǎng)度,也就是說(shuō)從當(dāng)前地址向后顯示幾個(gè)地址的內(nèi)容;f 表示顯示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示從當(dāng)前地址往后請(qǐng)求的字節(jié)數(shù),如果不指定的話,GDB默認(rèn)是4字節(jié)。u參數(shù)可以被一些字符代替:b表示單字節(jié),h表示雙字節(jié),w表示四字節(jié),g表示八 字節(jié)。當(dāng)我們指定了字節(jié)長(zhǎng)度后,GDB會(huì)從指定的內(nèi)存地址開(kāi)始,讀寫(xiě)指定字節(jié),并把其當(dāng)作一個(gè)值取出來(lái)。n、f、u這3個(gè)參數(shù)可以一起使用,例如命令 “x/3uh 0x54320” 表示從內(nèi)存地址0x54320開(kāi)始以雙字節(jié)為1個(gè)單位(h)、16進(jìn)制方式(u)顯示3個(gè)單位(3)的內(nèi)存。 ==

譬如下面的例子:

      
        main()

{

        
      
      
        char
      
       *c = 
      
        "
      
      
        hello world
      
      
        "
      
      
        ;

        printf(
      
      
        "
      
      
        %s\n
      
      
        "
      
      
        , c);

}
      
    

我們?cè)?

        
          char
        
         *c = 
        
          "
        
        
          hello world
        
        
          "
        
        ;
      

下一行設(shè)置斷點(diǎn)后:

            
              (gdb) l


            
            
              1
            
            
                  main()


            
            
              2
            
            
                  {


            
            
              3
            
            
              char
            
             *c = 
            
              "
            
            
              hello world
            
            
              "
            
            
              ;


            
            
              4
            
                    printf(
            
              "
            
            
              %s\n
            
            
              "
            
            
              , c);


            
            
              5
            
            
                  }

(gdb) b 
            
            
              4
            
            
              

Breakpoint 
            
            
              1
            
             at 
            
              0x100000f17
            
            : 
            
              file
            
             main.c, line 
            
              4
            
            
              .

(gdb) r

Starting program: 
            
            /Users/songbarry/
            
              main

Reading symbols 
            
            
              for
            
             shared libraries +. 
            
              done
            
            
              



Breakpoint 
            
            
              1
            
            , main () at main.c:
            
              4
            
            
              4
            
                    printf(
            
              "
            
            
              %s\n
            
            
              "
            
            , c);
          

可以通過(guò)多種方式看C指向的字符串:

方法1:

        
          (gdb) p c

$
        
        
          1
        
         = 
        
          0x100000f2e
        
        
          "
        
        
          hello world
        
        
          "
        
      

方法2:

        (gdb) x/s 
        
          0x100000f2e
        
        
          0x100000f2e
        
        :     
        
          "
        
        
          hello world
        
        
          "
        
      

方法3:

        (gdb) p (
        
          char
        
         *)
        
          0x100000f2e
        
        
          

$
        
        
          3
        
         = 
        
          0x100000f2e
        
        
          "
        
        
          hello world
        
        
          "
        
      

將第一個(gè)字符改為大寫(xiě):

        (gdb) p *(
        
          char
        
         *)
        
          0x100000f2e
        
        =
        
          '
        
        
          H
        
        
          '
        
        
          

$
        
        
          4
        
         = 
        
          72
        
        
          '
        
        
          H
        
        
          '
        
      

再看看C:

        
          (gdb) p c

$
        
        
          5
        
         = 
        
          0x100000f2e
        
        
          "
        
        
          Hello world
        
        
          "
        
      

9、set命令

修改寄存器:

        (gdb) set $v0 = 
        
          0x004000000
        
        
          

(gdb) set $epc 
        
        = 
        
          0xbfc00000
        
      

修改內(nèi)存:

        (gdb) set {unsigned 
        
          int
        
        }
        
          0x8048a51
        
        =
        
          0x0
        
      

譬如對(duì)于第8節(jié)的例子:

        (gdb) set {unsigned 
        
          int
        
        }
        
          0x100000f2e
        
        =
        
          0x0
        
        
                 

(gdb) x
        
        /10cb 
        
          0x100000f2e
        
        
          0x100000f2e
        
        :    
        
          0
        
        
          '
        
        
          \0
        
        
          '
        
        
          0
        
        
          '
        
        
          \0
        
        
          '
        
        
          0
        
        
          '
        
        
          \0
        
        
          '
        
        
          0
        
        
          '
        
        
          \0
        
        
          '
        
        
          111
        
        
          '
        
        
          o
        
        
          '
        
        
          32
        
        
          '
        
        
          '
        
        
          119
        
        
          '
        
        
          w
        
        
          '
        
        
          111
        
        
          '
        
        
          o
        
        
          '
        
        
          0x100000f36
        
        :    
        
          114
        
        
          '
        
        
          r
        
        
          '
        
        
          108
        
        
          '
        
        
          l
        
        
          '
        
        
          

(gdb) p c

$
        
        
          10
        
         = 
        
          0x100000f2e
        
        
          ""
        
      

10、jump命令

一般來(lái)說(shuō),被調(diào)試程序會(huì)按照程序代碼的運(yùn)行順序依次執(zhí)行,但是GDB也提供了亂序執(zhí)行的功能,也就是說(shuō),GDB可以修改程序的執(zhí)行順序,從而讓程序隨意跳躍。這個(gè)功能可以由GDB的jump命令: jump <linespec> 來(lái)指定下一條語(yǔ)句的運(yùn)行點(diǎn)。 <linespec> 可以是文件的行號(hào),可以是 file:line 格式,也可以是 +num 這種偏移量格式,表示下一條運(yùn)行語(yǔ)句從哪里開(kāi)始。 jump <address> 這里的 <address> 是代碼行的內(nèi)存地址。 注意,jump命令不會(huì)改變當(dāng)前的程序棧中的內(nèi)容,所以,如果使用jump從一個(gè)函數(shù)跳轉(zhuǎn)到另一個(gè)函數(shù),當(dāng)跳轉(zhuǎn)到的函數(shù)運(yùn)行完返回,進(jìn)行出棧操作時(shí)必然會(huì)發(fā)生錯(cuò)誤,這可能導(dǎo)致意想不到的結(jié)果,所以最好只用jump在同一個(gè)函數(shù)中進(jìn)行跳轉(zhuǎn)。

11、signal命令

使用singal命令,可以產(chǎn)生一個(gè)信號(hào)量給被調(diào)試的程序,如中斷信號(hào) “Ctrl+C” 。這非常方便于程序的調(diào)試,可以在程序運(yùn)行的任意位置設(shè)置斷點(diǎn),并在該斷點(diǎn)用GDB產(chǎn)生一個(gè)信號(hào)量,這種精確地在某處產(chǎn)生信號(hào)的方法非常有利于程序的調(diào)試。 signal命令的語(yǔ)法是: signal <signal> ,UNIX的系統(tǒng)信號(hào)量通常從1到15,所以 <signal> 取值也在這個(gè)范圍。

12、return命令

如果在函數(shù)中設(shè)置了調(diào)試斷點(diǎn),在斷點(diǎn)后還有語(yǔ)句沒(méi)有執(zhí)行完,這時(shí)候我們可以使用return命令強(qiáng)制函數(shù)忽略還沒(méi)有執(zhí)行的語(yǔ)句并返回。

            
              return

return 
            
            <expression>
          

上述return命令用于取消當(dāng)前函數(shù)的執(zhí)行,并立即返回,如果指定了 <expression> ,那么該表達(dá)式的值會(huì)被作為函數(shù)的返回值。

13、call命令

call命令用于強(qiáng)制調(diào)用某函數(shù): call <expr> 表達(dá)式中可以一是函數(shù),以此達(dá)到強(qiáng)制調(diào)用函數(shù)的目的,它會(huì)顯示函數(shù)的返回值(如果函數(shù)返回值不是void)。 其實(shí),前面介紹的print命令也可以完成強(qiáng)制調(diào)用函數(shù)的功能。

14、info命令

info命令可以在調(diào)試時(shí)用來(lái)查看寄存器、斷點(diǎn)、觀察點(diǎn)和信號(hào)等信息。

要查看寄存器的值,可以使用如下命令:

info registers (查看除了浮點(diǎn)寄存器以外的寄存器)

info all-registers (查看所有寄存器,包括浮點(diǎn)寄存器)

info registers <regname ...> (查看所指定的寄存器)

info break 查看斷點(diǎn)信息

info watchpoints 列出當(dāng)前所設(shè)置的所有觀察點(diǎn),

  i nfo signals info handle 查看有哪些信號(hào)正在被GDB檢測(cè),

  info line命令來(lái)查看源代碼在內(nèi)存中的地址。

  info threads可以看多線程。

  info line后面可以跟行號(hào)、函數(shù)名、文件名:行號(hào)、文件名:函數(shù)名等多種形式,例如下面的命令會(huì)打印出所指定的源碼在運(yùn)行時(shí)的內(nèi)存地址:

        
          info
        
         line tst.c:func
      

15、set scheduler-locking off|on|step

off 不鎖定任何線程,也就是所有線程都執(zhí)行,這是默認(rèn)值。
on 只有當(dāng)前被調(diào)試程序會(huì)執(zhí)行。
step 在單步的時(shí)候,除了next過(guò)一個(gè)函數(shù)的情況以外,只有當(dāng)前線程會(huì)執(zhí)行。

與多線程調(diào)試相關(guān)的命令還包括:

thread ID
  切換當(dāng)前調(diào)試的線程為指定ID的線程。?
break thread_test.c:123 thread all
  在所有線程中相應(yīng)的行上設(shè)置斷點(diǎn)
thread apply ID1 ID2 command
  讓一個(gè)或者多個(gè)線程執(zhí)行GDB命令command。
thread apply all command
  讓所有被調(diào)試線程執(zhí)行GDB命令command。

16、disassemble

disassemble命令用于反匯編,它可被用來(lái)查看當(dāng)前執(zhí)行時(shí)的源代碼的機(jī)器碼,其實(shí)際上只是把目前內(nèi)存中的指令dump出來(lái)。下面的示例用于查看函數(shù)func的匯編代碼:

      
        (gdb) disassemble func

Dump of assembler code 
      
      
        for
      
      
        function
      
      
         func:


      
      
        0x8048450
      
       <func>:       push   %
      
        ebp


      
      
        0x8048451
      
       <func+
      
        1
      
      >:     mov    %esp,%
      
        ebp


      
      
        0x8048453
      
       <func+
      
        3
      
      >:     sub    $
      
        0x18
      
      ,%
      
        esp


      
      
        0x8048456
      
       <func+
      
        6
      
      >:     movl   $
      
        0x0
      
      ,
      
        0xfffffffc
      
      (%
      
        ebp)

...

End of assembler dump.
      
    

?本文轉(zhuǎn)載自: http://blog.csdn.net/21cnbao/article/details/7385161

Linux gdb調(diào)試器用法全面解析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 欧美日日日 | 欧美成人一区二区三区在线视频 | 久久99精品久久久久久 | 午夜色a大片在线观看免费 龙珠z在线观看 | 国产1级片| 波多野结衣一区二区三区 | 亚洲一区二区三区在线免费观看 | 亚洲精品久久久久中文字幕欢迎你 | 久久99精品久久久久久 | 精品视频一区二区三区在线观看 | 欧美久久久久 | 欧美视频在线观看 | 日日爽夜夜爽 | 久操视屏 | 欧美日韩精品一区二区三区四区 | 成人免费一区二区三区视频网站 | www.色哟哟 | 国产精品久久久久久亚洲色 | 欧美第一页 | 亚洲高清在线播放 | 国产亚洲精品久久久极品美女 | 国产成人aaa在线视频免费观看 | 亚洲国产综合网 | 国产手机在线αⅴ片无码观看 | 国产网站大全 | 91麻豆国产极品在线观看洋子 | 国产高清免费 | 男女真实无遮挡xx00动态图120秒 | 欧美在线观看a | 国产成人精品一区二三区 | 欧美日韩久久久 | 免费观看成人碰视频公开 | 国产美女啪 | 一级特黄女人生活片 | 亚州综合| 欧美精品福利 | 日韩一区二区免费看 | 久操中文 | 精品一区二区三区不卡 | 孕妇体内谢精满日本电影 | 久久精品久久精品 |