使用 gdb 進行除錯
GNU 除錯器 (gdb) 可讓您在程式執行時檢查另一個程式的內部,或追溯查看程式在當機時所執行的動作。
gdb 可讓您檢查及控制程式碼的執行,有助於評估當機或一般不正確行為的原因。 gdb 不會處理 Java™ 處理程序,因此在純 Java 程式上只能使用它。 它對於原生程式庫及 JVM 本身的除錯非常有用。
執行 gdb
您可以透過三種方式來執行 gdb :
- 啟動程式
- 一般而言,指令:
gdb <application>
是用來在 gdb的控制下啟動程式。 不過,由於 Java 的啟動方式,您必須透過設定環境變數然後呼叫 Java 來啟動 gdb :
然後您會收到 gdb 提示,並提供執行指令和 Java 引數:export IBM_JVM_DEBUG_PROG=gdb java
r <java_arguments>
- 連接執行中程式
- 如果 Java 程式已在執行中,您可以在 gdb下控制它。 需要執行中程式的處理程序 ID ,然後啟動 gdb ,並以 Java 應用程式作為第一個引數,並以處理程序 ID 作為第二個引數:
gdb <Java Executable> <PID>
當 gdb 連接至執行中程式時,會中止此程式,並針對檢視器顯示其在程式碼中的位置。 然後,程式會在 gdb 的控制下,您可以開始發出指令來設定及檢視變數,並通常控制程式碼的執行。
- 在系統傾出上執行 (核心檔案)
- 當程式損毀時,通常會產生系統傾出。 gdb 可以在此系統傾出上執行。 系統傾出包含發生損毀時程式的狀態。 使用 gdb 來檢查導致損毀的所有變數及暫存器的值。 此資訊可協助您探索造成損毀的原因。 若要對系統傾出進行除錯,請以 Java 應用程式檔案作為第一個引數,並以系統傾出名稱作為第二個引數,來啟動 gdb :
gdb <Java Executable> <system dump>
當您針對系統傾出執行 gdb 時,它一開始會顯示一些資訊,例如程式收到的終止信號、當時正在執行的函數,甚至產生錯誤的程式碼行。
當程式受到 gdb控制時,會顯示歡迎使用訊息,後面接著提示 (gdb)。 程式現在正在等待您輸入指示。 對於每一個指示,程式會以您選擇的方式繼續執行。
設定岔斷點和監控點
可以使用下列指令來設定特定行或函數的岔斷點:
break linenumber
或
break functionName
設定岔斷點之後,請使用 continue 指令,讓程式執行到到達岔斷點為止。
請使用條件式來設定岔斷點,以便只有在達到指定的條件時,程式才會中止。 例如,使用 breakpoint 39 if var == value 會導致程式在達到第 39 行時中止,但只有在變數等於指定的值時。
如果您想要知道 where 以及 when 變數變成特定值,您可以使用監控點。 當有問題的變數在範圍內時,設定監控點。 在這樣做之後,每當此變數達到指定的值時,即會警示您。 指令的語法為: watch var == value。
若要查看已設定哪些岔斷點及監控點,請使用 info 指令:
info break
info watch
handle sig32 pass nostop noprint
handle sigusr2 pass nostop noprint
檢查程式碼
backtrace
(縮寫為 bt
) ,它會顯示呼叫堆疊。 呼叫堆疊是函數框的集合,其中每一個函數框都包含函數參數及區域變數等資訊。 這些函數訊框會依其執行順序放置在呼叫堆疊上。 這表示最近呼叫的函數會顯示在呼叫堆疊頂端。 您可以透過檢查呼叫堆疊來追蹤程式的執行軌跡。 當顯示呼叫堆疊時,它會在行的開頭顯示訊框號碼,接著是呼叫函數的位址,接著是函數名稱及函數的原始檔。 例如:#6 0x804c4d8 in myFunction () at myApplication.c
若要檢視函數頁框的更詳細資訊,請使用 frame
指令以及指定頁框號碼的參數。 選取頁框之後,您可以使用指令 print var
來顯示其變數。
使用 print
指令來變更變數的值; 例如 print var = newValue
。
info
locals
指令會顯示所選函數中所有區域變數的值。
若要遵循程式執行的確切順序,請使用 step
及 next
指令。 這兩個指令都採用選用參數,指定要執行的行數。 不過, next
會將函數呼叫視為單一執行行,而 step
會在所呼叫函數的每一行進行,一次一個步驟。
有用的指令
當您完成程式碼除錯時, run
指令會使程式一直執行到其結束或其損毀點。 quit
指令用來結束 gdb。
其他有用的指令如下:
ptype
- 列印變數的資料類型。
info share
- 列印目前載入的共用程式庫名稱。
info functions
- 列印所有函數原型。
list
- 顯示現行行周圍的 10 行原始碼。
help
- 顯示主題清單,其中每一個主題都可以呼叫說明指令,以顯示該主題的詳細說明。