30分鍾入門GDB


更多精彩內容,請關注微信公眾號:后端技術小屋

GDB全稱GDB Debugger。GDB具備各種調試功能,使用GDB的調試人員可以查看及修改程序的內部變量值。它是Linux C++開發者賴以生存的神器。本篇文章將簡要介紹GDB常用功能,希望對於初學者能起到快速入門的作用。

1. 綁定進程

gdb ./a.out       # 綁定尚未運行的程序
gdb attach <pid>  # 綁定正在運行的進程

2. 查看代碼

2.1 查看程序代碼

> dir <source_directory>    # 添加cpp原文件目錄
> l                         # 默認顯示暫停處代碼
> l   <function>            # 顯示函數代碼
> l   <file:function>       # 顯示文件中某函數代碼
> l   <file:line>           # 顯示文件中指定行數代碼

2.2 查看匯編指令

> disass                    # 顯示當前匯編指令
> display/i $pc             # 每次回到gdb命令行時,顯示當前匯編指令

3. 斷點

3.1 斷點設置

> b <file:line>                    # 設置文件中某行斷點
> b <file:function>                # 設置文件中某函數斷點
> b <namespace::class::function>   # 設置某類的成員函數斷點
> b <location> <thread-id>         # 設置某個線程在某處的斷點 
> b <location>  if <condition>     # 設置某處的條件斷點

3.2 斷點查看

> info  b                          # 查詢所有斷點

3.3 斷點刪除/啟用/禁用

> d <break-id>                      # 刪除某斷點
> disable   <break-id>              # 禁用某斷點
> enable    <break-id>              # 啟用某斷點

3.4 斷點設置自動執行命令

> command <break-id>
> p <var>                         # 運行到斷點處時自動打印變量<var>
> end

4. 線程調試

pstack <pid>      # 可事先dump某個進程下所有線程的thread id和backtrace,方便gdb調試
> info  threads               # 查看當前所有線程信息
> bt                          # 查看當前線程的backtrace
> bt full                     # 查看當前線程更詳細的backtrace(每個棧幀上的參數)
> thread <thread-id>          # 切換到某一個線程
> set scheduler-locking on    # 多線程環境下,只有當前被調試線程會執行
> set scheduler-locking off   # 多線程環境下,除當前被調試線程之外的其他線程也在同步執行
> set scheduler-locking step  # 多線程環境下,對當前被調試線程用step調試時,其他線程不會執行;使用next調試時,其他線程也許會執行

5. 運行控制

> r arg1 arg2 ...             # 重新開始運行二進制
> stop                        # 暫停運行
> c                           # 繼續執行
> n                           # 單步執行,遇到函數則跳過
> s                           # 單步執行,遇到函數則跳入函數體
> finish                      # 運行直到跳出當前函數
> until  line                 # 運行直到到達指定行
> call command                # 運行C++命令
> shell                       # 進入shell模式,回到linux終端
> exit                        # 退出shell模式,回到gdb命令行

> set $var=XXX                # 設置gdb變量
> set var=XXX                 # 設置程序中變量

6. 結束調試

detach # 如果通過gdb attach調試,detach之后,原進程將繼續執行
quit # 退出gdb

7. 調試core

一般情況下,當設置了ulimit -c unlimited之后,當程序遇到異常時,會自動轉儲core文件,方便開發者查看分析現場。

但是,如果想對一個正常運行的進程進行轉儲, 可使用gcore命令:

gcore <pid>             # 將進程<pid>轉儲到core文件中
gdb -c core ./a.out     # 調試core文件
> bt full               # 查看異常的backtrace

8. 代碼窗口

gdb命令行中輸入CTRL + X或者CTRL + A,即可調出代碼窗口,再按一次退出代碼窗口。

注意: 在tui模式下,無法使用方向鍵獲取上一條或下一條命令,可使用ctrl+p和ctrl+n替代

9. 打印變量

9.1 打印普通變量

> p <var>                     # 打印變量<var>

9.2 打印protobuf message

> p <var>.DebugString()       # 使用DebugString()將proto對象內部結構打印出來

9.3 打印內存地址

# n:為正整數,表示需要打印的內存單元個數
# 
# f:打印格式, 如下
# - x: 十六進制
# - d: 十進制
# - u: 十六進制
# - o: 八進制
# - t: 二進制
# - a: 十六進制
# - c: 字符格式
# - f: 浮點數
# 
# u: 內存單元大小,如下:
# - b: 單字節
# - h: 雙字節
# - w: 四字節
# - g: 八字節
# 
# addr: 要打印的內存地址 
> x/<n/f/u>  <addr>   # 打印內存地址

9.4 打印長字符串

gdb會限制打印字符串的最大長度。使用下列命令可修改限制:

> show print elements  # 顯示字符串最大打印長度
> set print elements 0 # 取消字符串最大打印長度

9.5 打印CPU寄存器的值

> i r                   # 打印所有寄存器的值
> i r es                # 打印寄存器es的值

10. 開啟日志

gdb默認不開啟日志。可使用如下命令開啟:

> set logging on       # 設置gdb日志開啟,gdb會在當前目錄下生成gdb.txt記錄gdb命令行所有輸出結果,方便回溯歷史。

推薦閱讀

更多精彩內容,請掃碼關注微信公眾號:后端技術小屋。如果覺得文章對你有幫助的話,請多多分享、轉發、在看。
二維碼


免責聲明!

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



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