編程工具系列之二------使用GDB的源代碼查看功能


      在調試程序的過程中,可以自由地查看相關的源代碼(如果有源代碼的話)是一項最基本的特性。
      一些IDE在這方面做得相當好,GDB當然也提供了這項特性,雖然不如IDE直觀,但在一定程度上要比IDE更加靈活和快捷。
      GDB之所以能夠知道對應的源代碼,是因為調試版的可執行程序中記錄了源代碼的位置;因為源代碼的位置在編譯之后可能會移動到其它地方,所以GDB還會在當前目錄中查找源代碼,另外GDB也允許明確指定源代碼的搜索位置。默認情況下,GDB在編譯時目錄中搜索,如果失敗則在當前目錄中搜索,即$cdir:$cwd,其中$cdir指的是編譯時目錄(compilation directory),$cwd指的是當前工作目錄(current working directory)。
      在GDB中使用查看源代碼相關的命令時,有一個當前文件的概念,當命令的位置參數沒有限定一個文件的時候(不論是明確限定還是隱含限定),將使用當前文件。當前文件默認是main函數所在文件,如果程序當前正處於斷點位置,則斷點所在文件即為當前文件。
      與當前文件的概念類似,還存在一個當前行的概念,它默認為main函數的開始處。如果使用gdb載入一個可執行文件,然后單單執行一條簡單的list命令,你會發現輸出的源代碼並非是從第一行開始的,這是因為當前行默認在main函數附近處的緣故。
      1.設置和獲取源代碼顯示數量:
         默認情況下,GDB顯示指定位置處以及其前后的10行代碼,但是這是一個可設置的值。
         set listsize count:設置list命令顯示的源代碼數量最多為count行,0表示不限制行數。
         show listsize:顯示listsize的值。
      2.編輯源代碼:
         在一些情況下,我們希望在編輯器中顯示或者編輯源代碼,GDB允許我們使用自己喜歡的編輯器。
         可在環境變量EDITOR中指定GDB使用的編輯器,例如:EDITOR=/usr/bin/gedit;export EDITOR;gdb
         edit location:在編輯器中編輯位置location處的源代碼,如果省略location,則編輯當前位置。
      3.搜索源代碼:
         有的時候,我們希望在當前文件中進行搜索,GDB提供了這樣的命令。
         search regexp:從當前行的下一行開始向前搜索。
         rev regexp :從當前行的上一行開始向后搜索。
         有的時候,你會發現search命令總是提示“Expression not found”,這是因為當前行可能已經是最后一行了,特別是文件很短的時候。這里需要注意的是,任何list命令都會影響當前行的位置,並且由於每次都是多行輸出,所以對當前行的影響並非簡單地向前一行或者向后一行。
          search命令本身也會影響當前行的位置。
      4.源代碼位置:
         GDB之所以可以查看到源代碼,是因為它知道源代碼放在哪里。
         在一個調試會話中,GDB維護了一個源代碼查找目錄列表,默認值是編譯目錄和當前工作目錄。當GDB需要一個源文件的時候,它依次在這些目錄中查找,直到找到一個或者拋出錯誤。
         GDB還維護了一個路徑替換規則,將要搜索的原始路徑按照找到的第一個規則做前綴替換,然后再在源碼搜索目錄中查找文件。
         GDB允許明確指定源代碼位置,或者路徑替換規則,以應付源代碼位置遷移的情況。
         directory path-list:將一個或者多個源代碼搜索目錄加入到當前源碼搜索目錄列表的前面,目錄之間使用空格間隔。
         directory:不帶參數的directory將源碼搜索目錄恢復為默認值。
         set directories path-list:將源碼目錄設置為path-list,但是會補上默認目錄。
         show directories:顯示源碼搜索目錄列表。
         set substitute-path from to:設置目錄替換規則,放置在規則列表的末端。
         unset substitute-path [path]:刪除path對應的替換規則,或者刪除所有的替換規則。
         show substitute-path [path]:顯示path對應的替換規則,或者顯示所有的替換規則。
      5.查看機器碼:
        在一些必要的時候,我們需要查看匯編代碼來診斷問題。GDB提供了這種可能。
        GDB提供了兩種能力:顯示源代碼位置與指令地址之間的映射;顯示指定位置的匯編代碼。
        info line linespec:顯示源代碼linespec處對應的匯編地址范圍。
        info line *addr:顯示地址addr處對應的源代碼位置。
        disassemble,disassemble /m,disassemble /r:顯示指定地址范圍內的匯編代碼,有4種使用形式,第一種不帶參數,顯示當前正在執行的函數的匯編代碼;第二           種是一個參數,顯示該地址所在函數的匯編代碼;第三種是兩個參數的disassemble start,end,顯示地址[start,end)內的匯編代碼;第四種是兩個參數的                       disassemble start,+length,顯示地址[start,start+length)內的匯編代碼。參數可以是16進制的地址,也可以是函數名。/m表示混合輸出源代碼和匯編代碼,/r表           示混合輸出二進制和匯編代碼。
        set disassembly-flavor instruction-set:設置顯示匯編代碼時使用的風格,目前只針對intel x86系列,可取的值為att和intel,默認是att。
        show disassembly-flavor:顯示disassembly-flavor設置
        set disassemble-next-line on|off|auto:當程序停止下來的時候,是否顯示下一行源代碼的匯編代碼,默認為off。
        show disassemble-next-line:顯示disassemble-next-line設置。
      6.顯示指定位置的源代碼:
        list命令可用於顯示指定位置處的源代碼。list命令會影響當前行和當前文件。
        list命令有多種方式指定要顯示的源代碼范圍,可以是行號,函數名,甚至是指令地址。
        常用的如下:
        list linenum:顯示指定行數附近的代碼。
        list function:顯示指定函數附近的代碼。
        list *addr:顯示指定地址附近的代碼。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM