目錄linux
首先使用gdb的前提是編譯的時候加上-g參數。例若有一下代碼c++
/* bugging.c */ #include <stdio.h> int foo(int n) { int sum; int i; for (i=0; i<=n; i++) { sum = sum+i; } return sum; } int main(int argc, char** argv) { int result = 0; int N = 100; result = foo(N); printf("1+2+3+...+%d= %d\n", N, result); return 0; }
首先編譯文件,若是gdb沒安裝的自行sudo安裝下shell
g++ bugging.c -g
1,敲擊run
執行程序,結果以下,退出爲quitbash
(gdb) run Starting program: /home/cwl/Desktop/code/gdb/gdbtest/a.out 1+2+3+...+100= 26895 [Inferior 1 (process 6322) exited normally]
其餘相關命令app
命令 | 簡寫形式 | 說明 |
---|---|---|
list | l | 查看源碼 |
backtrace | bt、where | 打印函數棧信息 |
next | n | 執行下一行 |
step | s | 一次執行一行,遇到函數會進入 |
finish | 運行到函數結束 | |
continue | c | 繼續運行 |
break | b | 設置斷點 |
info breakpoints | 顯示斷點信息 | |
delete | d | 刪除斷點 |
p | 打印表達式的值 | |
run | r | 啓動程序 |
until | u | 執行到指定行 |
info | i | 顯示信息 |
help | h | 幫助信息 |
在 gdb 命令行界面,輸入 help command
能夠查看命令的用法,command 是你想要查詢的命令。函數
在 gdb 命令行界面能夠執行外部的 Shell 命令:!shell 命令
ui
list 行號 list 文件名:行號 list 函數名
break 行號,斷點設置在該行開始處,注意:該行代碼未被執行 break 文件名 : 行號,適用於有多個源文件的狀況。 break 函數名,斷點設置在該函數的開始處,斷點所在行未被執行: break 文件名 : 函數名,適用於有多個源文件的狀況。
info breakpoints 命令用於顯示當前斷點信息。 其中 --- Num 列表明斷點編號,該編號能夠做爲 delete/enable/disable 等控制斷點命令的參數 Type 列表明斷點類型,通常爲 breakpoint Disp 列表明斷點被命中後,該斷點保留(keep)、刪除(del)仍是關閉(dis) Enb 列表明該斷點是 enable(y) 仍是 disable(n) Address 列表明該斷點處虛擬內存的地址 What 列表明該斷點在源文件中的信息
delete Num,刪除指定斷點,斷點編號可經過 info breakpoints 得到: delete,不帶任何參數,默認刪除全部斷點:
disable 命令和 enable 命令分別用於關閉和啓用斷點:spa
disable 命令用於關閉斷點,有些斷點可能暫時不須要但又不想刪除,即可以 disable 該斷點。命令行
enable 命令用於啓用斷點。調試
disable Num,關閉指定斷點,斷點編號可經過 info breakpoints 得到: disable,不帶任何參數,默認關閉全部斷點。 enable Num,啓用指定斷點,斷點編號可經過 info breakpoints 得到。 enable,不帶任何參數,默認啓用全部斷點。
disable 和 enable 命令影響的是 info breakpoints 的 Enb 列,表示該斷點是啓用仍是關閉
調試的過程當中須要觀察變量或者表達式的值,因此先介紹兩個基本的顯示變量值的命令:
info locals
打印當前斷點處所在函數的全部局部變量的值,不包括函數參數。
print 變量或表達式
打印表達式的值,可顯示當前函數的變量的值、全局變量的值等
print/FMT
能夠控制打印的格式,常見的有x(十六進制)、t(二進制)、c(顯示爲字符)等。
run 命令用於啓動待調試程序,並運行到斷點處停下。
run
不帶任何參數,啓動待調試程序,不傳遞參數。
run 參數
有些程序須要跟參數,直接帶上參數列表便可,會傳遞給 main 函數的 argc、argv 變量。
next, step, finish, continue, until 用於控制整個調試過程當中,程序執行的流程。
next
next 單步執行,函數調用當作一條指令,不會進入被調用函數內部
next N,表示單步執行N次
step
step 單步執行,會進入到函數調用內部
step N,表示單步執行N次
finish
執行程序到當前函數結束
continue
執行程序到下個斷點
until
until N,執行程序到源代碼的某一行
gdb bugging > (gdb) break foo > (gdb) info breakpoints run info proc mappings #查看待調試進程的內存分佈狀況
下面[STACK]就是進程棧空間了
process 12217 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x555555554000 0x555555555000 0x1000 0x0 /home/cwl/Desktop/code/gdb/gdbtest/a.out 0x555555754000 0x555555755000 0x1000 0x0 /home/cwl/Desktop/code/gdb/gdbtest/a.out 0x555555755000 0x555555756000 0x1000 0x1000 /home/cwl/Desktop/code/gdb/gdbtest/a.out 0x555555756000 0x555555777000 0x21000 0x0 [heap] 0x7ffff70f2000 0x7ffff72a3000 0x1b1000 0x0 /lib/x86_64-linux-gnu/libc-2.27.so 0x7ffff72a3000 0x7ffff74a2000 0x1ff000 0x1b1000 /lib/x86_64-linux-gnu/libc-2.27.so 0x7ffff74a2000 0x7ffff74a6000 0x4000 0x1b0000 /lib/x86_64-linux-gnu/libc-2.27.so 0x7ffff74a6000 0x7ffff74a8000 0x2000 0x1b4000 /lib/x86_64-linux-gnu/libc-2.27.so 0x7ffff74a8000 0x7ffff74ac000 0x4000 0x0 0x7ffff74ac000 0x7ffff74c3000 0x17000 0x0 /lib/x86_64-linux-gnu/libgcc_s.so.1 0x7ffff74c3000 0x7ffff76c2000 0x1ff000 0x17000 /lib/x86_64-linux-gnu/libgcc_s.so.1 0x7ffff76c2000 0x7ffff76c3000 0x1000 0x16000 /lib/x86_64-linux-gnu/libgcc_s.so.1 0x7ffff76c3000 0x7ffff76c4000 0x1000 0x17000 /lib/x86_64-linux-gnu/libgcc_s.so.1 0x7ffff76c4000 0x7ffff7856000 0x192000 0x0 /lib/x86_64-linux-gnu/libm-2.27.so 0x7ffff7856000 0x7ffff7a55000 0x1ff000 0x192000 /lib/x86_64-linux-gnu/libm-2.27.so 0x7ffff7a55000 0x7ffff7a56000 0x1000 0x191000 /lib/x86_64-linux-gnu/libm-2.27.so 0x7ffff7a56000 0x7ffff7a57000 0x1000 0x192000 /lib/x86_64-linux-gnu/libm-2.27.so 0x7ffff7a57000 0x7ffff7bc9000 0x172000 0x0 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 0x7ffff7bc9000 0x7ffff7dc9000 0x200000 0x172000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 0x7ffff7dc9000 0x7ffff7dd3000 0xa000 0x172000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 0x7ffff7dd3000 0x7ffff7dd5000 0x2000 0x17c000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 ---Type <return> to continue, or q <return> to quit--- 0x7ffff7dd5000 0x7ffff7dd8000 0x3000 0x0 0x7ffff7dd8000 0x7ffff7dfd000 0x25000 0x0 /lib/x86_64-linux-gnu/ld-2.27.so 0x7ffff7fce000 0x7ffff7fd4000 0x6000 0x0 0x7ffff7ff7000 0x7ffff7ffa000 0x3000 0x0 [vvar] 0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso] 0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x24000 /lib/x86_64-linux-gnu/ld-2.27.so 0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x25000 /lib/x86_64-linux-gnu/ld-2.27.so 0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0 0x7ffffffdc000 0x7ffffffff000 0x23000 0x0 [stack] 0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
backtrace 查看函數調用棧的狀況
backtrace、where、info stack
這三個命令均可以查看函數的調用狀況
backtrace full、where full、info stack full
這三個命令查看函數調用狀況的同時,打印全部局部變量的值
棧幀(stack frame)
#1 是 main 函數用到的棧空間,這一部分能夠稱之爲 main 函數的 stack frame
#0 是 foo 函數用到的棧空間,一樣可稱之爲 foo 函數的 stack frame,0 表明當前執行停在 foo 函數內
能夠獲得函數調用關係爲,main 調用 foo
info frame Num 查看某個函數棧幀的詳細信息
(gdb) info frame 0 # <=============== commond ================== Stack frame at 0x7fffffffcbd0: rip = 0x555555554680 in foo (bugging.c:13); saved rip = 0x5555555546b8 called by frame at 0x7fffffffcc00 source language c++. Arglist at 0x7fffffffcbc0, args: n=100 Locals at 0x7fffffffcbc0, Previous frame's sp is 0x7fffffffcbd0 Saved registers: rbp at 0x7fffffffcbc0, rip at 0x7fffffffcbc8 (gdb) info frame 1 # <=============== commond ================== Stack frame at 0x7fffffffcc00: rip = 0x5555555546b8 in main (bugging.c:24); saved rip = 0x7ffff7113a87 caller of frame at 0x7fffffffcbd0 source language c++. Arglist at 0x7fffffffcbf0, args: argc=1, argv=0x7fffffffccd8 Locals at 0x7fffffffcbf0, Previous frame's sp is 0x7fffffffcc00 Saved registers: rbp at 0x7fffffffcbf0, rip at 0x7fffffffcbf8