gdb命令調試技巧
一、信息顯示
1、顯示gdb版本 (gdb) show version
2、顯示gdb版權 (gdb) show version or show warranty
3、啟動時不顯示提示信息gdb -q exe 或者.bashrc 添加alias gdb="gdb -q",重啟shell
4、退出時不顯示提示信息(gdb) set confirm off
5、輸出信息多時不會暫停輸出(gdb)set pagination off
二、函數
1、列出函數的名字(gdb) info functions
2、是否進入待調試信息的函數(gdb)step s
3、進入不帶調試信息的函數(gdb)set step-mode on
4、退出正在調試的函數(gdb)return expression 或者 (gdb)finish
5、直接執行函數(gdb)start 函數名 call函數名
6、打印函數堆棧幀信息(gdb)info frame or i frame
7、查看函數寄存器信息(gdb)i registers
8、查看函數反匯編代碼(gdb)disassemble func
9、打印尾調用堆棧幀信息(gdb)set debug entry-values 1
10、選擇函數堆棧幀(gdb)frame n
11、向上或向下切換函數堆棧幀(gdb)up n down n
三、斷點
1、在匿名空間設置斷點(gdb)b Foo::foo (gdb) b (anonymous namespace)::bar
2、在程序地址上打斷點(gdb)b *address (gdb) b *0x400522
3、在程序入口處打斷點$strip a.out $readelf -h a.out或者(gdb)info files定位Entry point: 0x400440 (gdb)b *0x400440
4、在文件行號上打斷點(gdb)b linenum (gdb)b file.cpp:linenum (gdb)info breakpoints
5、保存已經設置的斷點(gdb)save breakpoints file-breakpoints-to-save (gdb)source file-breakpoints-to-save
6、設置臨時斷點(gdb)tbreak linenum
7、設置條件斷點(gdb)b linenum if cond b 11 if i==10
8、忽略斷點(gdb)ignore bnum count
四、觀察點
1、設置觀察點(gdb)watch a wacth *(type*)adress info watchpoints disable、enable、delete
2、設置觀察點只針對特定線程生效(gdb)info threads watch expr thread threadnum wa a thread 2
3、設置讀觀察點(gdb)rwatch
4、設置讀寫觀察點(gdb)awacth
五、Catchpoint
1、讓catchpoint只觸發一次(gdb)tcatch
2、為fork調用設置catchpoint (gdb)catch fork
3、為vfork調用設置catchpoint (gdb)catch vfork
4、為exec調用設置catchpoint (gdb)catch exec
5、為系統調用設置catchpoint (gdb)catch syscall name or num
6、通過ptrace調用設置catchpoint破解anti-debugging的程序 (gdb)catch syscall ptrace set $rax=0
六、打印
1、打印ASCII和寬字符字符串 (gdb)x/s str x/ws 4_wstr x/hs 2_wstr
2、打印STL容器中的內容 (gdb)p vec
3、打印大數組中的內容 (gdb)set print elements number-of-elements set print elements 0 or set print elements unlimited
4、打印數組中任意連續的元素值(gdb)p array[index]@num
5、打印數組的索引下標(gdb)set print array-indexes on
6、打印函數局部變量的值(gdb)bt full info locals
7、打印進程的內存信息(gdb)i proc mappings i files
8、打印靜態變量的值(gdb)p 'static-1.c'::var
9、打印變量的類型和所在文件(gdb)whatis he ptype he i variables he
10、打印內存的值(gdb)16進制 x/16xb a 10進制x/16ub a 二進制x/16tb a
11、打印源代碼行(gdb)l line l 函數 l - l + l 1,10
12、每行打印一個結構體成員(gdb)set print pretty on
13、按照派生類打印對象(gdb)set print object on
14、指定程序的輸入輸出設備(gdb)tty gdb -tty /dev/pts/2 ./a.out tty /dev/pts/2
15、使用"$\\_"和"$\\__"變量(gdb) x "命令會把最后檢查的內存地址值存在“ $_ ”這個“convenience variable”中,並
且會把這個地址中的內容放在“ $__ ”這個“convenience variable”
16、打印程序動態分配內存的信息(gdb)define mallocinfo set $__f = fopen("/dev/tty", "w") call malloc_info(0, $__f)call fclose($__f)end mallocinfo
17、打印調用棧幀中變量的值(gdb)b func_1 r bt f 1 p b f 2 p b p func2::b p func_3::b
七、多進程/線程
1、調試已經運行的進程gdb program -p=10210 (gdb)attach pid detach
2、調試子進程(gdb)set follow-fork-mode child
3、同時調試父進程和子進程(gdb)set detach-on-fork off i inferiors set schedule-multiple on
4、查看線程信息(gdb)i threads
5、在Solaris上使用maintenance命令查看線程信息(gdb)maint info sol-threads
6、不顯示線程啟動和退出信息(gdb)set print thread-events off
7、只允許一個線程運行(gdb)set scheduler-locking on
8、使用"$_thread"變量(gdb)command 2Type commands for breakpoint(s) 2, one per line.End with a line saying just "end".>printf "thread id=%d\n", $_thread >end
9、一個gdb會話中同時調試多個程序(gdb)add-inferior [ -copies n ] [ -exec executable ]
10、打印程序進程空間信息(gdb)maint info program-spaces
11、使用"$_exitcode"變量(gdb)p $_exitcode
八、core dump文件
1、為調試進程產生core dump文件(gdb)generate-core-file or gcore
2、加載可執行程序和core dump文件(gdb)gdb -q /data/nan/a /var/core/core.a.22268.1402638140
九、匯編
1、設置匯編指令格式(gdb)set disassembly-flavor intel disassemble main
2、在函數的第一條匯編指令打斷點(gdb)b *main
3、自動反匯編后面要執行的代碼(gdb)set disassemble-next-line on set disassemble-next-line auto set disassemble-next-line off
4、將源程序和匯編指令映射起來(gdb)disas /m main
5、顯示將要執行的匯編指令(gdb)display /i $pc
6、打印寄存器的值(gdb)i registers i all-registers i registers eax
7、顯示程序原始機器碼(gdb)disassemble /r main
十、改變程序執行順序
1、改變字符串的值(gdb)set main::p1="Jil"
2、設置變量的值(gdb)set var variable=expr set var i = 8 set {int}0x8047a54 = 8 set var $eax = 8
3、修改PC寄存器的值(gdb)p $pc set var $pc=0x08050949
4、跳轉到指定位置執行(gdb)j 15
5、使用斷點命令改變程序的執行(gdb)(gdb) b drawing Breakpoint 1 at 0x40064d: file win.c, line 6.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>set variable n = 0
>continue
>end
(gdb) r
6、修改被調試程序的二進制文件gdb -write ./a.out (gdb)show write set write on disassemble /mr drawing set variable *(short*)0x400651=0x0ceb disassemble /mr drawing
十一、信號
1、查看信號處理信息(gdb)i signals
2、信號發生時是否暫停程序(gdb) handle signal stop/nostop
3、信號發生時是否打印信號信息(gdb)handle signal print/noprint
4、信號發生時是否把信息丟給程序處理(gdb)handle signal pass(noignore)/nopass(ignore)
5、給程序發送信息(gdb)signal signal_name
6、使用"$_siginfo"變量(gdb)ptype $_siginfo
十二、共享庫
1、顯示共享連接庫信息(gdb)info sharedlibrary regex
十三、腳本
1、配置gdb init文件(gdb) home目錄下的 .gdbinit
2、按何種方式解析腳本文件(gdb)set script-extension off soft strict
3、保存歷史命令(gdb)set history filename ~/.gdb_history set history save on
十四、源文件
1、設置源文件查找路徑(gdb)directory ../ki/
2、替換查找源文件的目錄(gdb)set substitute-path from to
十五、圖形化界面
1、進入和退出圖形化調試界面(gdb)gdb -tui program
2、顯示匯編代碼窗口(gdb)layout asm
3、顯示寄存器窗口(gdb)layout regs
4、調整窗口大小(gdb)winheight <win_name> [+ | -]count
十六、其它
1、命令行選項的格式(gdb)gdb -help
2、支持預處理器宏信息(gdb)gcc -g3
3、使用命令的縮寫形式(gdb)b -> break
c -> continue
d -> delete
f -> frame
i -> info
j -> jump
l -> list
n -> next
p -> print
r -> run
s -> step
u -> until
aw -> awatch
bt -> backtrace
dir -> directory
disas -> disassemble
fin -> finish
ig -> ignore
ni -> nexti
rw -> rwatch
si -> stepi
tb -> tbreak
wa -> watch
win -> winheight
4、在gdb中執行shell命令和make(gdb)shell ls
5、在gdb中執行cd和pwd命令(gdb)pwd cd tmp
6、設置命令提示符(gdb)gdb -q `which gdb
7、設置被調試程序的參數(gdb)gdb -args ./a.out a b c set args a b c r a b
8、設置被調試程序的環境變量(gdb)set env varname=value
9、得到命令的幫助信息(gdb)help
10、記錄執行gdb的過程(gdb)set logging file log.txt set logging on