GDB調試之暫停


暫停機制: 有3種方式可以通知GDB暫停程序的執行。

          a.斷點: 通知GDB在程序中的特定位置暫停執行;

          b.監視點:通知GDB當特定內存位置(或者涉及一個或多個位置的表達式)的值發生變化時暫停執行;

          c.捕獲點: 通知GDB當特定事件發生時暫停執行;

容易混淆的是,在GDB文檔中將這3個機制都稱為斷點。這可能是因為它們的很多屬性和命令都相同;

GDB關於刪除斷點的delete命令:刪除斷點、監視點和捕獲點;

GDB中關於“位置”的含義非常靈活,它可以指各種源代碼行、代碼地址、源代碼文件中的行號或者函數的入口等;

           設置格式: 文件名:行號

斷點可以通過函數名,當前文件內的行號來設置,也可以先指定文件名再指定行號,還可以指定與暫停位置的偏移量,或者用地址來設置;

 

程序員創建的每個斷點(包括斷點、監視點、和捕獲點)都被標識為從1開始的唯一整數標識符;這個標識符用來執行該斷點上的各種操作,

         break function   在函數function() 的入口(第一行可執行代碼)處設置斷點,

      例如: break main 在源文件filename的line處設置斷點,如果filename不在當前目錄中,則可以給出相對路徑名或者完全路徑名來幫助GDB查找該文件。

      例如: break  source/bed.c:35 break bed.c:function

      臨時斷點(只生效一次): 使用tbreak命令設置,它與break采用相同類型的參數,

  在任何給定時間,GDB都有一個焦點,可以將它看作當前“活動”文件,這意味着除非對命令做了限定。否則都是在具有GDB的焦點的文件上執行命令。

           默認情況下,具有GDB的初始焦點的文件是包含main()函數的文件,但是當發生如下任一動作時,焦點會轉移到不同的文件上;

                   1、向不同的源文件應用list命令; list function

                   2、進入位於不同的源文件文件中的代碼;

                   3、當在不同的源代碼文件中執行代碼時GDB遇到斷點; 在調試會話期間不應退出GDB,

        例如,當發現並修復了一個程序錯誤,但是其他程序錯誤仍然存在時,不應當退出GDB然后重新進入來使用程序的新版本。這樣做有些不必要地繁瑣, 而且還會不得不重新進入斷點; 如果在修改和重新編譯代碼時沒有退出GDB,那么下次執行GDB是的run命令時,GDB會感知到代碼修改,並自動重新加載新版本;

          假如要關機了,又想保存GDB的斷點等信息;那怎么辦呢? 可以將斷點放在源代碼所在目錄的.gdbinit 啟動文件中;

          例如,當發現並修復了一個程序錯誤,但是其他程序錯誤仍然存在時,不應當退出GDB然后重新進入來使用程序的新版本。這樣做有些不必要地繁瑣, 而且還會不得不重新進入斷點; 如果在修改和重新編譯代碼時沒有退出GDB,那么下次執行GDB是的run命令時,GDB會感知到代碼修改,並自動重新加載新版本;

             如果要波啊流斷點以便用戶使用,暫時又不希望GDB停止執行; 可以禁用它們,在以后需要時再啟用。

      使用disable breakpoint-list命令禁用斷點。

             enable breakpoint-list命令啟用斷點;

                  其中breakpoint_list是使用空格分隔的列表,其中有一個或多個斷點標識符;

                disable不帶參數執行,將禁用所有現有斷點,enable也一樣; i b命令也能指出特定斷點引起GDB停止程序執行多是次; 使用commands命令設置命令列表:

              其中breakpoint-number是要將命令添加到其上的斷點的標識符,commands是用新行分隔的任何有效GDB命令列表。

              逐條輸入命令,然后鍵入end表示命令完畢。

              從那以后,每當GDB在這個斷點處中斷時,它都會執行你輸入的任何命令。

              commands breakpoint-number

              ......

             commands

             ......

             end

例如:

             commands 1

             printf   "var value is %d\n", n

              end

對比:

           commands 1

           silent

           printf  "var value is %d\n", n

            end

GDB的define命令創建宏

           define print_and_go

           printf  "%d\n", n

           continue

           end

監視點: 它是一種特殊類型的斷點,是要求GDB暫停程序執行的指令。

          區別在於監視點沒有“住在”某一行源代碼中,而是,監視點是指示GDB每當某個表達式改變了值就暫停執行的指令。

 例如:

            watch i 它會使得每當i改變值時GDB就暫停;

            display命令(簡寫disp):這個命令要求GDB在執行中每次有暫停(由於有斷點,使用next、step命令等)時就輸出指定條目;

             disp i 查看i的值; 通過GDB中的call命令來調用源代碼中的函數:

            例如:

                   commands 2

                   printf "************"

                   call function(參數)

                    end

 人工數組(artificial array)

                      *pointer@number_of_elements p

                       p         *x@25 GDB中, (監視局部變量)

                      info locals 命令得到當前棧幀中哦所有局部變量的值列表;

                     GDB中檢查內存 在有些情況下,可能希望檢測給定地址的內存,而不是通過變量的名稱。

                   x命令; p/x var GDB中設置當前的某個變量的值;

                    set x = 12 set args命令設置程序的命令行參數:

                    set args 1 2 4 檢查當前函數參數的info args命令:

 全局變量:errno 在文件/usr/include/linux/errno.h    或 /usr/include/asm-generic/errno.h  中有對錯誤數值的詳細解釋;

使用strace,跟蹤程序做過的所有系統調用;

關於網絡的調試,Ethereal程序跟蹤單個TCP/IP分組;

與線程相關的GDB命令用法匯總:

確定每個線程在做什么,可以通過 GDB的info threads來確定:

檢查線程1:   thread  1

break  88 thread  3 (當線程3達到源代碼行88時停止執行)

break 88  thread 3 if  x==y  (當線程3到達3源代碼行88,並且變量x和y相等時停止執行)

 

layout next 命令: 源代碼、匯編、二進制之間轉換

 還有一組專用的gdb變量可以用來檢查和修改計算機的通用寄存器,gdb提供了每一台計算機中實際使用的4個寄存器的標准名字:

  $pc  : 程序計數器

  $fp  : 幀指針(當前堆棧幀)

  $sp : 棧指針

  $ps : 處理器狀態

 


免責聲明!

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



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