日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GDB调试基础操作详解【GDB调试】

發(fā)布時間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GDB调试基础操作详解【GDB调试】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  • 什么是bug
  • 什么是調(diào)試
  • 什么是調(diào)試器
  • 注意
  • 啟動調(diào)試與程序執(zhí)行
    • 啟動調(diào)試并傳遞啟動參數(shù)
      • 方式一:啟動gdb調(diào)試時添加參數(shù)
      • 方式二:啟動gdb調(diào)試之后執(zhí)行r之前設置參數(shù)
      • 方式三:啟動gdb調(diào)試之后執(zhí)行r時設置參數(shù)
    • 附加到進程進行調(diào)試(調(diào)試正在運行的程序)
      • 方式一:gdb attach [pid]
      • 方式二:gdb --pid [pid]
    • 開始執(zhí)行
    • 逐過程執(zhí)行
    • 逐語句執(zhí)行
    • 繼續(xù)執(zhí)行
    • 退出函數(shù)
    • 退出調(diào)試
      • detach(分離)
      • q (退出)
  • 斷點管理
    • 在源碼某一行設置斷點
    • 為函數(shù)設置斷點
    • 為滿足正則表達式的函數(shù)設置斷點
    • 設置條件斷點
    • 設置臨時斷點
    • 查看所有斷點
    • 查看指定斷點
    • 禁用斷點
    • 啟用斷點
    • 刪除指定斷點
    • 刪除所有斷點
  • 變量的查看與修改
    • 查看函數(shù)所有參數(shù)
    • 查看變量的值
    • 設置字符串顯示格式
    • 設置結構體顯示格式
    • 設置數(shù)組顯示規(guī)則
    • gdb內(nèi)嵌操作
      • sizeof
      • strlen
      • strcmp
      • strcpy
    • 修改變量
      • 修改基本變量
      • 修改字符串
      • 修改結構體
  • 內(nèi)存的查看與修改
    • 查看內(nèi)存
      • 查看第一個內(nèi)存地址的地址及對應的值
      • 查看從該地址開始的[數(shù)字]個字節(jié)的值
      • 查看字符串地址對應的字符串
      • 顯示從該字符串地址開始的[數(shù)字]個字節(jié)的值
      • 顯示結構體[數(shù)字]個字節(jié)體在內(nèi)存中的值
    • 修改內(nèi)存
  • 寄存器的查看與修改
    • 查看寄存器
      • 函數(shù)參數(shù)個數(shù) <= 6 個通過寄存器傳遞
      • 函數(shù)參數(shù)個數(shù) > 6 個通過函數(shù)棧傳遞
      • 查看所有通用寄存器
      • 查看所有寄存器
      • 查看一個寄存器
    • 修改寄存器
      • 查看源碼對應的反匯編地址
      • 改變程序執(zhí)行流程
  • 源代碼的管理、查看、搜索
    • 顯示源代碼
    • 向后顯示源代碼
    • 向前顯示源代碼
    • 顯示指定函數(shù)的源代碼
    • 顯示指定類中指定函數(shù)的源代碼
    • 顯示指定行的源代碼
    • 設置顯示行數(shù)
    • 搜索源代碼
      • search 正則表達式
      • forward-search 正則表達式
      • reverse-search 正則表達式
      • 查找源代碼的路徑
  • 函數(shù)調(diào)用棧管理
    • 查看棧回溯信息
    • 切換棧幀
    • 查看棧幀信息

什么是bug

現(xiàn)在指的是硬件或軟件中的故障、缺陷、錯誤等。

什么是調(diào)試

從代碼中去除bug。

什么是調(diào)試器

附加到程序,幫助審查代碼找到bug的工具。

注意

gdb調(diào)試程序,使用 makefile 編譯時需要在 CFLAGS 加上 -g 參數(shù)。
編譯完成之后會攜帶程序的調(diào)試信息,方便調(diào)試(同時程序也會變大很多)。

gdb開始調(diào)試程序之后有 reading symbols from [可執(zhí)行程序名]
表示編譯之后的程序帶有調(diào)試信息,可以很方便進行調(diào)試。

啟動調(diào)試與程序執(zhí)行

啟動調(diào)試并傳遞啟動參數(shù)

方式一:啟動gdb調(diào)試時添加參數(shù)

命令:gdb --args [應用程序名] [啟動參數(shù)]
舉例:gdb --args section1 1 2 "3 4"

方式二:啟動gdb調(diào)試之后執(zhí)行r之前設置參數(shù)

命令:set args [啟動參數(shù)]
舉例:set args 1 2 "3 4"

方式三:啟動gdb調(diào)試之后執(zhí)行r時設置參數(shù)

命令:r [啟動參數(shù)]
舉例:r 1 2 "3 4"

附加到進程進行調(diào)試(調(diào)試正在運行的程序)

方式一:gdb attach [pid]

舉例:gdb attach 198237
調(diào)試過程中,程序退出調(diào)試也會自動結束。

方式二:gdb --pid [pid]

舉例:gdb --pid 198237
調(diào)試過程中,程序退出調(diào)試也會自動結束。

開始執(zhí)行

命令:r
開始執(zhí)行程序,運行到第一個斷點中斷。
如果沒有設置斷點,程序會直接執(zhí)行結束。

逐過程執(zhí)行

命令:n
單步執(zhí)行,遇到函數(shù)跳過函數(shù)。

逐語句執(zhí)行

命令:s
單步執(zhí)行,遇到函數(shù)進入到函數(shù),停留到函數(shù)的第1行。
如果沒有當前執(zhí)行沒有函數(shù),則和 n 效果相同。

繼續(xù)執(zhí)行

命令:c
繼續(xù)執(zhí)行,直到遇到下一個斷點。

退出函數(shù)

命令:finish
如果當前執(zhí)行在函數(shù)中,執(zhí)行會退出當前函數(shù),執(zhí)行到調(diào)用當前函數(shù)的下一行。

退出調(diào)試

detach(分離)

從程序分離,退出調(diào)試之后對于正在執(zhí)行的程序無影響。

調(diào)試正在運行的程序:(對于調(diào)試的程序運行無影響)
①:attach進來調(diào)試。
②:detach分離退出調(diào)試。

q (退出)

命令:q
會提示:退出調(diào)試程序將會被強制退出。

斷點管理

在源碼某一行設置斷點

命令:b [文件名]:[行號]
舉例:b main.cpp:38
在 main.cpp 文件的 38行設置斷點。

為函數(shù)設置斷點

命令:b [函數(shù)名]
舉例:b test_fun
在所有同名函數(shù)的第一行都設置斷點。

為滿足正則表達式的函數(shù)設置斷點

命令:rb [正則表達式]
舉例:rb work
為每個帶有work的函數(shù)都設置斷點。

設置條件斷點

命令:b [文件名]:[行號] [條件]
舉例:b main.cpp:14 if i==90 設置在main.cpp 14行,當i為90時,滿足條件設置斷點。
滿足條件設置斷點。

設置臨時斷點

命令:tb [文件名]:[行號]
舉例:tb main.cpp:14 在main.cpp 14行設置一個臨時斷點。
臨時斷點只會命中一次,一旦中斷之后,后面不會再中斷停下來。(即使是在循環(huán)中。)
中斷一次之后自動刪除。

查看所有斷點

命令:i b
查看所有斷點信息。

查看指定斷點

命令:i b 2
查看 2 號斷點的詳細信息。

禁用斷點

命令:disable [斷點編號]
舉例:disable 1
斷點存在,但是不會在該斷點命中停止。

啟用斷點

命令:enable [斷點編號]
舉例:enable 1
啟用被禁用的斷點,使程序運行到該斷點時命中停止。

刪除指定斷點

命令:delete [斷點編號]
舉例:delete 1
刪除斷點編號為 1 的斷點。

刪除所有斷點

命令:delete
刪除所有斷點。

變量的查看與修改

查看函數(shù)所有參數(shù)

命令:info args

查看變量的值

命令:p [變量名]
變量名可以是:基本類型變量、字符串、結構體、數(shù)組等。

通過字符串地址查看字符串:
命令:p (char *)[十六進制地址]
舉例:p (char *)0x555555556005
查看字符串變量的地址和字符串。

設置字符串顯示格式

命令:set print null-stop
查看時,字符串不顯示后面的\0

設置結構體顯示格式

命令:set print pretty
結構體按照定義的方式顯示,一行一個元素。

設置數(shù)組顯示規(guī)則

命令:set print array on
類似結構體按照定義的方式顯示,一行一個元素。

gdb內(nèi)嵌操作

sizeof

命令:p sizeof(int)
查看 int 類型所占字節(jié)數(shù)。

test 為結構體變量。
命令:p sizeof(test)
查看結構體 test所占字節(jié)數(shù)。

strlen

name 為字符串名稱。
命令:p strlen(name)
查看字符串長度。

strcmp

name1和name2為字符串名稱
命令:p strcmp(name1, name2)
比較兩個字符串的大小。

strcpy

name是結構體p的數(shù)據(jù)成員。
命令:p strcpy(p.name, "Soft")
字符串拷貝。

修改變量

通過修改變量改變程序運行的邏輯,按照我們期望的邏輯運行。

修改基本變量

i 為定義的臨時變量。
命令:p i=5
將 i 的值改為 5。

修改字符串

name 為字符串名稱。
命令:p name="Simple"

修改結構體

age為test結構體成員。
命令:p test.age = 25

內(nèi)存的查看與修改

查看內(nèi)存

命令:x /選項 [任意內(nèi)存地址]

查看第一個內(nèi)存地址的地址及對應的值

命令: x [內(nèi)存地址]
舉例:x 0x7fffffffe334
不指定選項只顯示第一個內(nèi)存地址的地址及對應的值。

查看從該地址開始的[數(shù)字]個字節(jié)的值

命令:x /[數(shù)字]b [內(nèi)存地址]
舉例:x /4b 0x7fffffffe334 顯示從 0x7fffffffe334 地址開始的4個字節(jié)數(shù)據(jù)。

查看字符串地址對應的字符串

命令:x /s [字符串名稱]
舉例:x /s test_str
字符串名稱本身就是字符串的地址。

顯示從該字符串地址開始的[數(shù)字]個字節(jié)的值

命令:x /10d [字符串名稱]
舉例:x /10d test_str
顯示從字符串開始地址開始10個字節(jié)的值。

顯示結構體[數(shù)字]個字節(jié)體在內(nèi)存中的值

命令:x/20b &[結構體變量名稱]
舉例:x/20b &test
顯示結構體20個字節(jié)體在內(nèi)存中的值。

修改內(nèi)存

命令:set {[強制轉換的類型]} & [變量名] = [修改后的值]
舉例:set {int} &test.gender = 110
將 test.gender 修改為 強制轉換為int 類型的 100。

寄存器的查看與修改

沒有調(diào)試符號、程序崩潰內(nèi)存遭到破壞或者已經(jīng)發(fā)布的程序,程序的運行狀態(tài)和內(nèi)存中的內(nèi)容很難查看。

程序運行時,很多數(shù)據(jù)存儲在寄存器中,函數(shù)的參數(shù)也是通過寄存器傳遞。

查看寄存器

函數(shù)參數(shù)個數(shù) <= 6 個通過寄存器傳遞

寄存器 函數(shù)參數(shù) rdi 第一個參數(shù) rsi 第二個參數(shù) rdx 第三個參數(shù) rcx 第四個參數(shù) r8 第五個參數(shù) r 第六個參數(shù)

函數(shù)參數(shù)個數(shù) > 6 個通過函數(shù)棧傳遞

查看所有通用寄存器

命令: i registers

查看所有寄存器

命令: i all-registers

查看一個寄存器

命令:i r [寄存器名字]
舉例:i r rdi

修改寄存器

查看源碼對應的反匯編地址

命令:info line [源代碼行數(shù)]
顯示源碼行數(shù)對應指令的開始地址和結束地址。

改變程序執(zhí)行流程

pc/rip寄存器:保存程序下一條要執(zhí)行的命令,通過修改pc寄存器來改變程序執(zhí)行的流程。

命令:

set var $pc=[開始地址] [開始地址是反匯編的地址,不是源代碼的地址] set var $rip=[開始地址] [開始地址是反匯編的地址,不是源代碼的地址] p $rip=[開始地址] [開始地址是反匯編的地址,不是源代碼的地址]

源代碼的管理、查看、搜索

顯示源代碼

命令:l
默認顯示10行代碼,當前執(zhí)行行在第6行。

向后顯示源代碼

命令:l
已經(jīng)通過 l 命令顯示10行源代碼之后,再執(zhí)行 l 向后顯示10行源代碼。

向前顯示源代碼

命令:l -
已經(jīng)通過 l 命令顯示10行源代碼之后,再執(zhí)行 l - 向后10行顯示源代碼。

顯示指定函數(shù)的源代碼

命令:l [函數(shù)名]
舉例:l test_fun
顯示函數(shù)代碼,函數(shù)定義頭在第6行顯示。
如果有多個重名函數(shù)定義,則會顯示所有重名函數(shù)。

顯示指定類中指定函數(shù)的源代碼

命令:l [類名]::[函數(shù)名]
舉例: l test_c::test_member

命令:l [文件名]:[函數(shù)名]
舉例: l main.cpp:test_member

顯示指定行的源代碼

命令:l [文件名]:[行號]
舉例:l main.cpp:10
顯示 main.cpp 文件第 10 行源代碼。

設置顯示行數(shù)

命令:set listsize [行數(shù)]
舉例:set listsize 5
舉例:set listsize 15

搜索源代碼

search 正則表達式

命令:search [模式匹配字段]
從當前代碼行向后查找所有和字段匹配的源代碼位置。

舉例:search test
從當前代碼行向后查找所有和 test 有關的源代碼。
開始執(zhí)行直接找到第一個匹配的位置,按 Enter 向后找到下一處,直到找到所有和字段匹配的代碼段。

forward-search 正則表達式

命令:forward-search [模式匹配字段]
和search功能相同。

reverse-search 正則表達式

命令:reverse-search [模式匹配字段]
從當前代碼行向前查找所有和字段匹配的源代碼位置。

舉例:reverse-search test
從當前代碼行向后查找所有和 test 有關的源代碼。
開始執(zhí)行直接找到第一個匹配的位置,按 Enter 向前找到下一處,直到找到所有和字段匹配的代碼段。

查找源代碼的路徑

命令:show directories
查找到兩個路徑:
①:程序所在目錄。
②:程序運行目錄。

如果源文件所在路徑無法找到,需要添加源文件搜索路徑。
命令:directory [源文件所在路徑]
舉例: directory source2/
將 source2/ 目錄添加到查找源代碼時的源文件搜索路徑。

函數(shù)調(diào)用棧管理

棧幀:程序進行函數(shù)調(diào)用時的調(diào)用信息,包括調(diào)用參數(shù),局部變量,寄存器等信息。
所有棧幀組成的信息稱為調(diào)用棧。

查看棧回溯信息

命令:bt
0 號棧幀在棧頂,表示當前正在執(zhí)行的函數(shù)。

切換棧幀

命令:f n
舉例:f 3
切換到 3 號棧幀。

命令:f [棧幀地址]
舉例:f 0x7fffffffe2f0
切換到棧幀地址為 0x7fffffffe2f0 對應的棧幀。
切換之后可以直接通過命令查看對應該函數(shù)參數(shù)和局部變量等信息。

查看棧幀信息

命令:info f n
舉例:info f 0
查看0號棧幀的詳細信息。
包括:棧幀地址,rip寄存器,參數(shù)信息。局部變量等信息。

總結

以上是生活随笔為你收集整理的GDB调试基础操作详解【GDB调试】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。