多線程調試可能是問得最多的。其實,重要就是下面幾個指令:
info thread 檢視目前程序的線程。
thread <id> 切換調試的線程為指定id的線程。
break file.c:100 thread all 在file.c檔案第100行處為所有經過這裡的線程設定斷點。
set scheduler-locking off|on|step,這個是問得最多的。在使用step或者continue指令調試目前被調試線程的時候,其他線程也是同時執行的,怎麼隻讓被調試程式執行呢?通過這個指令就可以實作這個需求。
off 不鎖定任何線程,也就是所有線程都執行,這是預設值。
on 隻有目前被調試程式會執行。
step 在單步的時候,除了next過一個函數的情況(熟悉情況的人可能知道,這其實是一個設定斷點然後continue的行為)以外,隻有目前線程會執行。
這個問題超多。在gdb下,我們無法print宏定義,因為宏是預編譯的。但是我們還是有辦法來調試宏,這個需要gcc的配合。
在gcc編譯程式的時候,加上-ggdb3參數,這樣,你就可以調試宏了。
另外,你可以使用下述的gdb的宏調試指令 來檢視相關的宏。
info macro – 你可以檢視這個宏在哪些檔案裡被引用了,以及宏定義是什麼樣的。
macro – 你可以檢視宏展開的樣子。
這個問題問的也是很多的,太多的朋友都說找不到源檔案。在這裡我想提醒大家做下面的檢查:
編譯程式員是否加上了-g參數以包含debug資訊。
路徑是否設定正确了。使用gdb的directory指令來設定源檔案的目錄。
下面給一個調試/bin/ls的示例(ubuntu下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<code>$ apt-get</code><code>source</code><code>coreutils</code>
<code>$</code><code>sudo</code><code>apt-get</code><code>install</code><code>coreutils-dbgsym</code>
<code>$ gdb</code><code>/bin/ls</code>
<code>gnu gdb (gdb) 7.1-ubuntu</code>
<code>(gdb) list main</code>
<code>1192</code><code>ls</code><code>.c: no such</code><code>file</code><code>or directory.</code>
<code>in</code><code>ls</code><code>.c</code>
<code>(gdb) directory ~</code><code>/src/coreutils-7</code><code>.4</code><code>/src/</code>
<code>source directories searched:</code><code>/home/hchen/src/coreutils-7</code><code>.4:$cdir:$cwd</code>
<code>1192 }</code>
<code>1193 }</code>
<code>1194</code>
<code>1195 int</code>
<code>1196 main (int argc, char **argv)</code>
<code>1197 {</code>
<code>1198 int i;</code>
<code>1199 struct pending *thispend;</code>
<code>1200 int n_files;</code>
<code>1201</code>
條件斷點是文法是:break [where] if [condition],這種斷點真是非常管用。尤其是在一個循環或遞歸中,或是要監視某個變量。注意,這個設定是在gdb中的,隻不過每經過那個斷點時gdb會幫你檢查一下條件是否滿足。
有時候,我們需要調試的程式需要有指令行參數,很多朋友都不知道怎麼設定調試的程式的指令行參數。其實,有兩種方法:
gdb指令行的 –args 參數
gdb環境中 set args指令。
有時候,在調試程式時,我們不單單隻是檢視運作時的變量,我們還可以直接設定程式中的變量,以模拟一些很難在測試中出現的情況,比較一些出錯,或是switch的分支語句。使用set指令可以修改程式中的變量。
另外,你知道gdb中也可以有變量嗎?就像shell一樣,gdb中的變量以$開頭,比如你想列印一個數組中的個個元素,你可以這樣:
<code>(gdb)</code><code>set</code><code>$i = 0</code>
<code>(gdb) p a[$i++]</code>
<code>...</code><code>#然後就一路回車下去了</code>
當然,這裡隻是給一個示例,表示程式的變量和gdb的變量是可以互動的。
也許,你很喜歡用p指令。是以,當你不知道變量名的時候,你可能會手足無措,因為p指令總是需要一個變量名的。x指令是用來檢視記憶體的,在gdb中 “help x” 你可以檢視其幫助。
x/x 以十六進制輸出
x/d 以十進制輸出
x/c 以單字元輸出
x/i 反彙編 – 通常,我們會使用 <code>x/10i $ip-20 來檢視目前的彙編($ip是指令寄存器)</code>
x/s 以字元串輸出
有一些朋友問我如何自動化調試。這裡向大家介紹command指令,簡單的了解一下,其就是把一組gdb的指令打包,有點像字處理軟體的“宏”。下面是一個示例:
<code>(gdb)</code><code>break</code><code>func</code>
<code>breakpoint 1 at 0x3475678:</code><code>file</code><code>test</code><code>.c, line 12.</code>
<code>(gdb)</code><code>command</code><code>1</code>
<code>type commands</code><code>for</code><code>when breakpoint 1 is hit, one per line.</code>
<code>end with a line saying just</code><code>"end"</code><code>.</code>
<code>>print arg1</code>
<code>>print arg2</code>
<code>>print arg3</code>
<code>>end</code>
<code>(gdb)</code>
當我們的斷點到達時,自動執行command中的三個指令,把func的三個參數值打出來。