GDB 調試工具高級用法


解決core核心文件轉出問題

ulimit -c #查看core文件的生成開關,若為0則關閉

ulimit -c unlimited #打開開關,只在當前shell生效

sudo sh -c 'echo "./%e.core.%p" > /proc/sys/kernel/core_pattern' #在當前目錄下生成core文件,臨時生效

啟動GDB

gdb ./process         #直接調試目標程序
gdb .
/process core  #調試轉儲文件
gdb <program> <PID>  #調試服務程序

開始調試

棧回溯顯示我們是如何到達失敗點的,通常足夠幫助我們確定常見的問題。

bt (backtrace的簡寫)常常是我在 gdb 中使用的第一條命令

gdb$ bt     #棧回溯,有core文件的情況下
disas main #反匯編main函數,或者其它出錯函數
i r     #(info registers 的簡寫)打印寄存器值
start    #開始調試,在main函數的第一條語句停下來 ; 等同於 break main

查看源代碼

  • list :簡記為 l ,其作用就是列出程序的源代碼,默認每次顯示10行。
  • list 行號:將顯示當前文件以“行號”為中心的前后10行代碼,如:list 12
  • list 函數名:將顯示“函數名”所在函數的源代碼,如:list main
  • list :不帶參數,將接着上一次 list 命令的,輸出下邊的內容

設置斷點

break 是設置斷點,可簡寫為b

b n  #在第n行源碼處設置斷點

b fn1 if a>b   #條件斷點設置

b func  #在func()函數入口點設置斷點

delete 斷點號n  #刪除第n個斷點

disable 斷點號n  #暫停第n個斷點

enable 斷點號n  #開啟第n個斷點

clear 行號n  #清除第n行的斷點

info b   #(info breakpoints)顯示當前程序的斷點設置情況

delete breakpoints  #清除所有斷點

交互命令

r  #運行此程序
c  #繼續運行
next  #單步步過
step  #單步步入
until  #一直運行程序,直到退出循環體
until+行號  #運行至某行,不僅僅用來跳出循環
finish  #運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值及參數值等信息
call 函數(參數)  #調用程序中可見的函數,並傳遞“參數”,如:call gdb_test(55)
q  #退出

打印表達式

print 表達式:簡記為 p ,其中“表達式”可以是任何當前正在被測試程序的有效表達式

比如當前正在調試C語言的程序,那么“表達式”可以是任何C語言的有效表達式,包括數字,變量甚至是函數調用

print a    #將顯示整數 a 的值
print name  #將顯示字符串 name 的值
p main    #打印main函數內容和地址
p buffer    #打印buffer內容
p &buffer    #打印buffer地址
info f  #這句也可以查到main函數地址,最后一行
  • display 表達式:在單步運行時將非常有用,使用display命令設置一個表達式后,它將在每次單步進行指令后,緊接着輸出被設置的表達式及值。如: display a
  • watch 表達式:設置一個監視點,一旦被監視的“表達式”的值改變,gdb將強行終止正在被調試的程序。如: watch a
  • whatis :查詢變量或函數
  • info function: 查詢函數
  • 擴展info locals: 顯示當前堆棧頁的所有變量

回退

gdb 有一個超棒的功能叫回退

這里我可以逐行或逐條指令的回退。它通過播放我們記錄的寄存器狀態來工作

reverse-stepi    #回退一條指令

用GDB查看內存

格式: x /nfu <addr>

x 是 examine 的縮寫

n 表示要顯示的內存單元的個數

f 表示顯示方式, 可取如下值

x 按十六進制格式顯示變量。
d 按十進制格式顯示變量。
u 按十進制格式顯示無符號整型。
o 按八進制格式顯示變量。
t 按二進制格式顯示變量。
a 按十六進制格式顯示變量。
i 指令地址格式
c 按字符格式顯示變量。
f 按浮點數格式顯示變量。

u 表示一個地址單元的長度

b 表示單字節
h 表示雙字節
w 表示四字節
g 表示八字節


Format letters are

o(octal), x(hex), d(decimal), u(unsigneddecimal)
t(binary), f(float), a(address), i(instruction), c(char) ands(string)


Size letters are

b(byte), h(halfword), w(word), g(giant, 8bytes)

舉例

x/3uh buf

 

表示從內存地址buf讀取內容
h 表示以雙字節為一個單位
3 表示三個單位
u 表示按十六進制顯示

詳細例子:

(gdb) list
#include
<stdio.h> int main() {   char a[1];   a[0]='a';   unsigned long long md5=14126471717450151013;   printf("%d/n",a[0]);   return 0; }
(gdb)
break 10 Breakpoint 1 at 0x8048372: file test.c, line 10. (gdb) run Starting program:/data/compiler/g_platform/bradenwu/md5/test.out Breakpoint 1, main () at test.c:10 10 return 0; (gdb) x/8xb md5 0x8837f465: Cannot access memory at address 0x8837f465 (gdb) x/8xb &md5 0xbfffefa0: 0x65 0xf4 0x37 0x88 0x2e 0x4f 0x0b 0xc4

 


免責聲明!

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



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