環境:gcc (OpenWrt/Linaro GCC 4.8)sass
以以下的簡單代碼爲例,說明gdb的使用。函數
1 void func1(int a, int b) 2 { 3 int c; 4 c = a + b; 5 } 6 7 int main(void) 8 { 9 10 func1(11,22); 11 return 100; 12 }
1. gdb 下一步的命令spa
a.執行下一行語句(語句級別)
next(或n) 執行下一行語句,若是是函數調用則直接將函數執行完;至關於visual studio調試器中的"Step Over (單步跟蹤)"
step(或s) 執行下一行語句,若是是函數調用則進入函數中。即常說的單步調試,至關於visual studio調試器中的"Step Into (單步跟蹤進入)"
這兩個命令必須在有源代碼調試信息的狀況下才可使用(GCC編譯時使用「-g」參數)
b.執行下一條指令(指令級)
si 相似於s;
ni 相似於n;
這兩個命令(si/ni)所針對的是彙編指令指針
2. disassemble調試
能夠反彙編當前函數或者指定的函數,
單獨用disassemble命令是反彙編當前函數,
若是disassemble命令後面跟函數名或地址,則反彙編指定的函數.日誌
(gdb) disassemble Dump of assembler code for function main: 0x00008440 <+0>: push {r11, lr} 0x00008444 <+4>: add r11, sp, #4 => 0x00008448 <+8>: mov r0, #11 0x0000844c <+12>: mov r1, #22 0x00008450 <+16>: bl 0x8410 <func1> 0x00008454 <+20>: mov r3, #100 ; 0x64 0x00008458 <+24>: mov r0, r3 0x0000845c <+28>: pop {r11, pc} End of assembler dump. (gdb) disassemble Dump of assembler code for function func1: 0x00008410 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008414 <+4>: add r11, sp, #0 0x00008418 <+8>: sub sp, sp, #20 0x0000841c <+12>: str r0, [r11, #-16] 0x00008420 <+16>: str r1, [r11, #-20] => 0x00008424 <+20>: ldr r2, [r11, #-16] 0x00008428 <+24>: ldr r3, [r11, #-20] 0x0000842c <+28>: add r3, r2, r3 0x00008430 <+32>: str r3, [r11, #-8] 0x00008434 <+36>: sub sp, r11, #0 0x00008438 <+40>: pop {r11} ; (ldr r11, [sp], #4) 0x0000843c <+44>: bx lr End of assembler dump.
3. 顯示寄存器的信息code
info registers能夠顯示全部寄存器的當前值(不包括浮點寄存器)blog
info all-registers(包括浮點寄存器)
簡寫: i r內存
1 (gdb) info registers 2 r0 0xb 11 3 r1 0x16 22 4 r2 0xbefffe2c 3204447788 5 r3 0x8440 33856 6 r4 0xbeffff14 3204448020 7 r5 0x8304 33540 8 r6 0xbefffc80 3204447360 9 r7 0x8 8 10 r8 0x0 0 11 r9 0x0 0 12 r10 0xb6ffef7c 3070226300 13 r11 0xbefffc64 3204447332 14 r12 0xbefffd68 3204447592 15 sp 0xbefffc50 0xbefffc50 16 lr 0x8454 33876 17 pc 0x8424 0x8424 <func1+20> 18 cpsr 0x60000010 1610612752 19 (gdb) i r 20 r0 0xb 11 21 r1 0x16 22 22 r2 0xbefffe2c 3204447788 23 r3 0x8440 33856 24 r4 0xbeffff14 3204448020 25 r5 0x8304 33540 26 r6 0xbefffc80 3204447360 27 r7 0x8 8 28 r8 0x0 0 29 r9 0x0 0 30 r10 0xb6ffef7c 3070226300 31 r11 0xbefffc64 3204447332 32 r12 0xbefffd68 3204447592 33 sp 0xbefffc50 0xbefffc50 34 lr 0x8454 33876 35 pc 0x8424 0x8424 <func1+20> 36 cpsr 0x60000010 1610612752
4.查看內存的值:ci
gdb中使用"x"命令來打印內存的值,格式爲"x/nfu addr"。含義爲以f格式打印從addr開始的n個長度單元爲u的內存值。參數具體含義以下:
a)n:輸出單元的個數。
b)f:是輸出格式。好比x是以16進制形式輸出,o是以8進制形式輸出,等等。
x(hex) 按十六進制格式顯示變量。
d(decimal) 按十進制格式顯示變量。
u(unsigned decimal) 按十進制格式顯示無符號整型。
o(octal) 按八進制格式顯示變量。
t(binary) 按二進制格式顯示變量。
a(address) 按十六進制格式顯示變量。
c(char) 按字符格式顯示變量。
f(float) 按浮點數格式顯示變量
c)u:標明一個單元的長度。b是一個byte,h是兩個byte(halfword),w是四個byte(word),g是八個byte(giant word)
1 舉例: 2 以16進制格式打印從add開始的16個byte的值: 3 (gdb) x/16xb $r11 4 0xbefffc64: 0x6c 0xfc 0xff 0xbe 0x00 0x00 0x00 0x00 5 0xbefffc6c: 0xc4 0xcc 0xfc 0xb6 0x00 0x90 0xfd 0xb6
5.打印棧幀信息:
frame 打印當前棧幀的簡要信息。
1 (gdb) frame 2 #0 func1 (a=11, b=22) at hello.c:17 3 17 in hello.c
6.info frame 打印當前棧幀的詳細信息。
1 (gdb) info frame 2 Stack level 0, frame at 0xbefffc68: 3 pc = 0x8434 in func1 (hello.c:17); saved pc 0x8454 4 called by frame at 0xbefffc70 5 source language c. 6 Arglist at 0xbefffc64, args: a=11, b=22 7 Locals at 0xbefffc64, Previous frame's sp is 0xbefffc68 8 Saved registers: 9 r11 at 0xbefffc64
7.info frame args 打印指定棧幀的詳細信息
1 (gdb) i f 1 2 Stack frame at 0xbefffc70: 3 pc = 0x8454 in main (hello.c:22); saved pc 0xb6fcccc4 4 caller of frame at 0xbefffc68 5 source language c. 6 Arglist at 0xbefffc6c, args: 7 Locals at 0xbefffc6c, Previous frame's sp is 0xbefffc70 8 Saved registers: 9 r11 at 0xbefffc68, lr at 0xbefffc6c
8.info args 打印函數參數信息
1 (gdb) info args 2 a = 11 3 b = 22
9.info locals 打印當前可訪問的局部變量的信息。
1 (gdb) info locals 2 c = 0
10.怎樣知道一個棧幀的大小?
fp和sp之間的區域就是一個函數的棧幀的大小。
fp通常是指r11寄存器。
sp通常是指r13寄存器。
1 (gdb) i r 2 r0 0xb 11 3 r1 0x16 22 4 r2 0xb 11 5 r3 0x8440 33856 6 r4 0xbeffff14 3204448020 7 r5 0x8304 33540 8 r6 0xbefffc80 3204447360 9 r7 0x8 8 10 r8 0x0 0 11 r9 0x0 0 12 r10 0xb6ffef7c 3070226300 13 r11 0xbefffc64 3204447332 14 r12 0xbefffd68 3204447592 15 sp 0xbefffc50 0xbefffc50 16 lr 0x8454 33876 17 pc 0x8428 0x8428 <func1+24> 18 cpsr 0x60000010 1610612752 19 20 (gdb) disassemble 21 Dump of assembler code for function func1: 22 0x00008410 <+0>: push {r11} ; (str r11, [sp, #-4]!) 23 => 0x00008414 <+4>: add r11, sp, #0 ;將sp中的內存地址放入r11,即設置fp 24 0x00008418 <+8>: sub sp, sp, #20 ;將sp中的內存地址減少20,即設置func1的棧頂指針,如上兩條指令執行完後,該函數的棧幀的大小就肯定了,20 bytes 25 0x0000841c <+12>: str r0, [r11, #-16] ;函數參數賦值,將r0中的值存入[r11, #-16]內存地址,即函數實參入棧 26 0x00008420 <+16>: str r1, [r11, #-20] ;函數參數賦值,將r1中的值存入[r11, #-16]內存地址 27 0x00008424 <+20>: ldr r2, [r11, #-16] 28 0x00008428 <+24>: ldr r3, [r11, #-20] 29 0x0000842c <+28>: add r3, r2, r3 30 0x00008430 <+32>: str r3, [r11, #-8] 31 0x00008434 <+36>: sub sp, r11, #0 32 0x00008438 <+40>: pop {r11} ; (ldr r11, [sp], #4) 33 0x0000843c <+44>: bx lr 34 End of assembler dump.
有時在調試過程當中,想記錄下來操做的過程及相關信息,那麼 執行set logging on便可打卡記錄,默認存在gdb.txt。
固然也能夠本身指定log文件,set logging file logname
set logging overwrite on
命令可讓輸出覆蓋以前的日誌文件;而 「set logging redirect on
」命令會讓gdb的日誌不會打印在終端