筆記:gdb debug指令概要
1. b/break設定中斷點
1.1 針對function名稱設定中斷點b func_name
gdb內可以用TAB的auto completion,預設最多顯示200筆資料(gdb) b avpriv_mpegts
avpriv_mpegts_parse_close avpriv_mpegts_parse_open avpriv_mpegts_parse_packet
(gdb) b avpriv_mpegts_parse_packet
Breakpoint 1 at 0x749540: file libavformat/mpegts.c, line 3369.
1.2 針對特定source code行數設定中斷點b file_name:line_num
(gdb) b libavformat/mpegts.c:3163Breakpoint 2 at 0x7451a7: file libavformat/mpegts.c, line 3163.
1.3 針對目前source code設定中斷點b line_num
(gdb) b 300Breakpoint 2 at 0x4971a7: file fftools/ffprobe.c, line 300.
如果你還沒有執行程式,b 300的意思是設定main程式所在檔案的第300行
例如ffprobe的main程式在fftools/ffprobe.c, 就會設定在ffprobe.c的300行
1.4 針對當前位置設定中斷點 b
(gdb) b1.5 顯示中斷點i b/info break
(gdb) i bNum Type Disp Enb Address What
1 breakpoint keep y 0x0000000000749540 in avpriv_mpegts_parse_packet at libavformat/mpegts.c:3369
2 breakpoint keep y 0x00000000007451a7 in mpegts_read_header at libavformat/mpegts.c:3163
1.6 關閉/啟用中斷點disable/enable breakponts
關閉第二個中斷點
(gdb) disable b 2
(gdb) i b
Num Type Disp Enb Address What
2 breakpoint keep n 0x00000000007424f0 in mpegts_probe at libavformat/mpegts.c:2997
4 breakpoint keep y 0x0000000000496750 in main at fftools/ffprobe.c:3584
breakpoint already hit 1 time
啟用所有中斷點
(gdb) enable b
(gdb) i b
Num Type Disp Enb Address What
2 breakpoint keep n 0x00000000007424f0 in mpegts_probe at libavformat/mpegts.c:2997
4 breakpoint keep y 0x0000000000496750 in main at fftools/ffprobe.c:3584
breakpoint already hit 1 time
1.7 儲存/載入中斷點save breakpoints/source
(gdb) save breakpoints bps.saved
將使用過的中斷點儲存到指定檔案名稱
(gdb) pwd
Working directory /main/ffmpeg.
(gdb) cd ../
Working directory /main.
1.8 刪除中斷點d/delete
刪除所有(gdb) d刪除特定中斷點,以info break上的Num為準(gdb) d 1
2. 執行程式
2.1 開始執行程式r/run
(gdb) rStarting program: ffmpeg/ffprobe_g -i /content/movie.ts
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ffprobe version N-96259-g481f4380fb Copyright (c) 2007-2020 the FFmpeg developers
...
如果你已經執行程式,會顯示是否重新執行
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n)
2.1.1 執行程式帶入新參數
(gdb) r -i /content/new_movie.ts
就會使用後面的參數執行程式
注意:有帶入過參數後,再使用r會一直沿用新的參數, 要清除需要用set args清除參數
2.1.2 設定新參數
(gdb) set args -i /content/new_movie.ts
只設定新參數
2.1.3 清除參數
(gdb) set args
清除參數執
2.1.4 顯示目前參數
(gdb) show args
注意:這裡不是用i args顯示內容,要顯示函數參數才是,因為set指令對應的顯示功能是show
2.2 繼續執行c/continue
當程式中斷後要讓程式繼續執行,需使用此功能(gdb) cBreakpoint 2, mpegts_probe (p=0x7fffffffd400) at libavformat/mpegts.c:2997
2997 #define CHECK_COUNT 10
2.3 停止程式kill
(gdb) kill會詢問是否確定將程式停止
3. 顯示source code
3.1 顯示執行位置的檔案及行號i li/info line
(gdb) i liLine 2997 of "libavformat/mpegts.c" starts at address 0x7424f0
3.2 顯示執行位置的對應source code, l/line
顯示source code預設是上下5行(gdb) l
2992 const int size = p->buf_size;
...
3001 return 0;
如果再次使用line會得到再下面的10行,如下所示
(gdb) l
3002
3003 for (i = 0; i
...
3010 maxscore = FFMAX(maxscore, score);
3011 }
使用l -可往上10行
使用l 100可顯示100行附近
使用l 100, 150可顯示100到150行內容
3.3 顯示執行位置的source code檔案相關訊息i source
Current source file is libavformat/mpegts.c
Compilation directory is ffmpeg
Located in ffmpeg/libavformat/mpegts.c
Contains 3415 lines.
Source language is c.
Producer is GNU C 4.8.5 -mtune=generic -march=x86-64 -g -O3 -std=c11 -fomit-frame-pointer -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -fstack-protector.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
4. 單步執行及呼叫堆疊
關於stack frame參考:http://kirste.userpage.fu-berlin.de/chemnet/use/info/gdb/gdb_7.html
4.1 往下一行執行n/next
3002
使用n 100可往下執行100行,其實這結果是很難預測的,可能會跑到函數結束,或是遭遇例外,使用後會需要用到info line或frame確認目前執行位置。
(gdb) i li
Line 196 of "libavformat/format.c" starts at address 0x6d1d81
and ends at 0x6d1d90
4.2 往下一步執行s/step
(gdb) s
相較於n,s就是往下一步執行,如果是函數,就會跳進去該函數執行。
如果要跳回來原本位置,可以用up或是finish執行到函數結束
4.3 呼叫堆疊
除了bt外,我們也可以用i s/info stack,f/frames顯示目前呼叫堆疊
(gdb) bt
#0 av_probe_input_format3 (pd=pd@entry=0x7fffffffd8b0, is_opened=is_opened@entry=1, score_ret=score_ret@entry=0x7fffffffd8a8)at libavformat/format.c:196
#1 0x00000000006d225e in av_probe_input_format2 (score_max=
at libavformat/format.c:208
#2 av_probe_input_buffer2 (pb=0x227fa40, fmt=0x227f208, filename=filename@entry=0x7fffffffe064 "/content/movie.ts",
logctx=logctx@entry=0x227f200, offset=offset@entry=0, max_probe_size=1048576) at libavformat/format.c:280
...
(gdb) s
parse_loglevel (argc=argc@entry=3, argv=argv@entry=0x7fffffffdc08, options=options@entry=0x119d200 )
at fftools/cmdutils.c:507
507 {
(gdb) frame
#0 parse_loglevel (argc=argc@entry=3, argv=argv@entry=0x7fffffffdc08, options=options@entry=0x119d200 )
at fftools/cmdutils.c:507
507 {
如果只想看特定堆疊,可以用frame 堆疊號碼來指定
(gdb) i f
Stack level 0, frame at 0xbe8a3570:
pc = 0xb2656f4c in nanosleep; saved pc = 0xb263b8fc
called by frame at 0xbe8a3598
Arglist at 0xbe8a3570, args:
Locals at 0xbe8a3570, Previous frame's sp is 0xbe8a3570
(gdb) up
(gdb) down
用這個指令,通常後面會搭配next執行下一行
4.4 執行到函數結束fi/finish
(gdb) finish
Run till exit from #0 mpegts_probe (p=0x7fffffffd810) at libavformat/mpegts.c:2997
av_probe_input_format3 (pd=pd@entry=0x7fffffffd8b0, is_opened=is_opened@entry=1, score_ret=score_ret@entry=0x7fffffffd8a8)
at libavformat/format.c:166
166 if (score)
Value returned is $1 = 50
5. 印出變數內容
5.1 顯示特定p/print var_name
(gdb) print sumscore
$7 = 0
(gdb) print dvhs_score
$8 =
上面可以看到$7,$8,這些都是臨時變數,也可以再印出一次, 使用 $ 來取用最後產生的臨時變數,使用 $$ 來取用上一個產生的臨時變數。
引用自:https://blog.csdn.net/u012927281/article/details/50546787
使用gdb過程中出現value optimized out,上述情況是由於gcc在編譯過程中默認使用-O2優化選項。以上情況在循環語句中經常出現,對於希望進行單步跟蹤調試時,應使用-O0選項。5.1.1 花式印出變數
(gdb) p &var 印出變數var的位址
(gdb) p *var 印出變數var取址後的值
(gdb) p/x var 以 16 進位列印變數var內容
(gdb) p/u var 以 unsigned 10 進位列印變數var內容
(gdb) p/d var 以 signed 10 進位列印變數var內容
(gdb) p/t var 以 2 進位列印變數var內容
(gdb) p (var=value) 設變數var的值為value
5.1.2 印出陣列
(gdb) p array[10] 印出陣列變數array第11個元素內容
(gdb) p array[1]@5 從陣列變數array第2個元素開始印出5個內容
5.1.3 印出資料
(gdb) whatis var 印出變數var資料型別
(gdb) ptype var 印出變數var的struct
參考:
http://www.study-area.org/cyril/opentools/opentools/x1253.html
5.2 印出local變數
(gdb) i locals
maxscore = 0
i =
...
5.3 印出register
(gdb) i reg
rax 0x7424f0 7611632
rbx 0x18878c0 25721024
...
5.4 印出函數的參數
(gdb) i args
argc = 3
argv = 0x7fffffffdc08
options = 0x119d200
6. 多執行緒操作
參考:https://sourceware.org/gdb/current/onlinedocs/gdb/Threads.html
6.1 印出執行緒狀態
(gdb) i threads
Id Target Id Frame
* 1 Thread 0x7ffff7f2e8c0 (LWP 13571) "ffprobe_g" mpegts_probe (p=0x7fffffffd810) at libavformat/mpegts.c:2997
6.2 切換到執行緒
(gdb) thread 1
6.3 綜合操作
如何查卡在哪個thread上面, 請參考
print mutax變數看屬性__owner去對照找出該thread
7. 多Process操作
https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-and-Programs.html
https://sourceware.org/gdb/onlinedocs/gdb/Forks.html
7.1 顯示Process資訊
顯示所有Process(gdb) i inferiors顯示目前Process
(gdb) i inferior
7.2 結束特定Process
(gdb) kill inferior 1
7.3 自動切換新Process
自動切換到新Process(gdb) set follow-exec-mode new
8. gdb其他東西
因為比較少用所以就先放這8.1 display持續顯示變數內容,這樣就不用一直打指令顯示
8.2 catchpint抓exception,syscall,fork,signal等等
https://sourceware.org/gdb/onlinedocs/gdb/Set-Catchpoints.html
8.3 使用command bt-num可以在gdb寫一些指令指定在中斷點發生時要做的事情, 例如列印變數之類的, 類似巨集
8.4 使用shell執行指令
8.5 結合python自動化使用,和一些gdb技巧
https://jaredcjr.blogspot.com/2016/08/gdbdebug.html
留言