JDB 快速指南



JDB - 簡介

除錯是一個技術過程,用於查詢並移除程式中的錯誤或缺陷,並獲得預期的結果。除錯包括測試和監控。當程式的子單元緊密耦合時,除錯會變得非常複雜。我們可以使用遵循規定的 API 的偵錯程式工具來除錯程式。偵錯程式允許您逐步瀏覽程式碼的每個方面,檢查所有元素,並消除任何錯誤。

除錯技術

有不同型別的技術可以用來除錯 Java 程式。舊的除錯方法是使用列印語句在每個段的末尾,這將在控制檯上列印跟蹤語句。請檢視以下程式碼。

pubic class Add
{
   public static void main(String ar[])
   {
      int a=ar[0];
      system.out.println("A : " +a);
      int b=ar[1];
      system.out.println("B : " +b);
      int c = a + b;
      system.out.println("C = a + b : " +c);
   }
}

這裡,我們有一個程式,它將兩個數字相加並列印輸出。請注意,在每個步驟中,我們都引入了一個列印語句,該語句在控制檯上列印程式的狀態。這是除錯程式的傳統方法。

此外,我們還有可以用來除錯程式的高階概念,例如

  • 單步執行
  • 斷點,以及
  • 異常或監視點。

除錯型別

我們可以使用多種方法除錯程式

  • 使用 Java 位元組碼(Java 程式碼的編譯版本)
  • 在程式內部使用註釋
  • 將類附加到正在執行的程式
  • 遠端除錯
  • 按需除錯
  • 最佳化程式碼除錯

Java 偵錯程式

以下是一些市面上可用的 Java 偵錯程式的示例

  • IDE(如 Eclipse、Netbeans 等)包含它們自己的偵錯程式(Visual cafe、Borland、JBuilder)
  • 獨立偵錯程式 GUI(如 Jikes、Java 平臺偵錯程式和 JProbe)
  • 命令列偵錯程式(Sun 的 JDB)
  • Notepad 或 VI 驅動(堆疊跟蹤)

本教程介紹如何使用命令列偵錯程式jdb

JDB

Java 偵錯程式 (JDB) 是一個用於 Java 類的工具,用於在命令列中除錯程式。它實現了 Java 平臺偵錯程式架構。它有助於使用 Java 除錯介面 (JDI) 檢測和修復 Java 程式中的錯誤。

JDK 中的 JDB

以下架構定義了 JDB 在 JDK 中的角色。它主要包含三個單元

  • Java 虛擬機器工具介面 (JVM TI)
  • Java 除錯線池 (JDWP)
  • Java 除錯介面 (JDI)
JDB Architecture

JVM TI

它是由 VM 實現的本機程式設計介面。它提供了檢查和除錯在 VM 上執行的應用程式狀態的方法。它允許實現者(VM 實現者)可以輕鬆地封裝到除錯架構中。它還使用名為JDWP的第三方通道進行通訊。

JDWP

它定義了在被除錯程序和偵錯程式前端之間傳遞的資訊和請求的格式。擁有 JDWP 的主要目的是允許被偵錯程式和偵錯程式在它們在單獨的 VM 或單獨的平臺上執行時進行通訊。

JDI

它是一個作為前端實現的高階 Java 介面。它定義了使用者程式碼級別上的變數資訊。建議對所有偵錯程式開發使用 JDI 層。它使用 JDWP 與被除錯的 JVM 通訊。

JDB - 安裝

本章說明如何在基於 Windows 和 Linux 的系統上安裝 JDB。JDB 是 JDK 的一部分。因此,JDK 安裝足以在命令提示符下使用 JDB。

系統要求

以下是安裝 JDB 的系統要求

JDK Java SE 2 JDK 1.5 或更高版本
記憶體 1 GB RAM(推薦)
磁碟空間 無最低要求
作業系統版本 Windows XP 或更高版本,Linux

按照以下給出的簡單步驟在您的系統上安裝 JDB。

步驟 1:驗證 Java 安裝

首先,您需要在您的系統上安裝 Java 軟體開發工具包 (SDK)。要驗證這一點,請根據您正在使用的平臺執行以下兩個命令中的任何一個。

如果 Java 安裝已正確完成,則它會顯示 Java 安裝的當前版本和規範。示例輸出在以下表格中給出。

平臺 命令 示例輸出
Windows

開啟命令控制檯並鍵入

\>java –version

Java 版本 "1.7.0_60"

Java (TM) SE 執行時環境 (build 1.7.0_60-b19)

Java Hotspot (TM) 64 位伺服器 VM (build 24.60-b09,混合模式)

Linux

開啟命令終端並鍵入

$java –version

java 版本 "1.7.0_25"

Open JDK 執行時環境 (rhel-2.3.10.4.el6_4-x86_64)

Open JDK 64 位伺服器 VM (build 23.7-b01,混合模式)

我們假設本教程的讀者在其系統上安裝了 Java SDK 版本 1.7.0_60。如果您沒有 Java SDK,請從連結http://www.oracle.com/technetwork/java/javase/downloads/index.html下載其當前版本並安裝它。

步驟 2:設定 Java 環境

設定環境變數 JAVA_HOME 以指向 Java 安裝在您計算機上的基本目錄位置。例如,

平臺 描述
Windows 將 JAVA_HOME 設定為 C:\ProgramFiles\java\jdk1.7.0_60
Linux export JAVA_HOME=/usr/local/java

將 Java 編譯器位置的完整路徑附加到系統路徑。

平臺 描述
Windows 在系統變數 PATH 的末尾附加字串 "C:\Program Files\Java\jdk1.7.0_60\bin"。
Linux export PATH=$PATH:$JAVA_HOME/bin/

從命令提示符執行命令java -version,如上所述。

步驟 3:驗證 JDB 安裝

如下驗證 JDB 版本

平臺 命令 示例輸出
Windows

開啟命令控制檯並鍵入

\>jdb –version

這是 JDB 版本 1.6(Java SE 版本 1.7.0_60)
Linux

開啟命令終端並鍵入

$jdb –version

這是 JDB 版本 1.6(Java SE 版本 1.7.0_60)

JDB - 語法

本章解釋了 JDB 命令的語法。語法包含以下列出的四個部分

  • JDB
  • 選項
  • 引數

語法

JDB 的語法如下。

jdb [ options ] [ class ] [ arguments ]

JDB

它從 Java 開發工具包呼叫 jdb.exe。

選項

這些包括用於以有效方式除錯 Java 程式的命令列選項。JDB 啟動器接受所有選項(例如 -D、-classpath 和 -X)以及一些其他高階選項(例如 (-attach、-listen、-launch 等)。

它是您要對其執行除錯操作的類名。

引數

這些是在執行時給定給程式的輸入值。例如,arg[0]、arg[1] 到 main() 方法。

在以上四個部分中,選項是最重要的一個。

JDB - 選項

本章描述了 JDB 中可用的重要選項,這些選項作為引數與 jdb 命令一起提交。

選項

下表包含 JDB 接受的選項列表

名稱 描述
-help 顯示幫助訊息並列出相關選項。
-sourcepath 如果未指定路徑,則使用給定路徑作為原始檔,否則它將採用預設路徑“.”,即當前目錄。
-attach 透過指定正在執行的 VM 地址將偵錯程式附加到正在執行的 VM。
-listen 等待正在執行的 VM 使用標準聯結器連線。
-listenany 等待正在執行的 VM 使用任何地址連線。
-launch 在啟動作業時立即啟動被除錯的應用程式。
-listconnectors 列出此 VM 中可用的聯結器。
-connect 使用命名聯結器和列出的引數值連線到目標 VM。
-dbgtrace 列印用於除錯 jdb 的資訊。
-tclient 在 Java Hotspot VM(客戶端)中執行應用程式。
-tserver 在 Java Hotspot VM(伺服器)中執行應用程式。
-Joption 將選項傳遞給用於執行 JDB 的 Java 虛擬機器。

將選項與命令一起使用

以下命令顯示如何使用上述一些選項

-help

以下命令獲取有關使用 JDB 的 -help。

\>jdb -help

-attach

以下命令將偵錯程式附加到指定的 VM(埠號:1099)。

\> jdb -attach 1099

-listen

以下命令使 JDB 程序在當前 VM 上使用標準聯結器等待(VM 在 8008)。

\>jdb -listen 8088

-listenany

以下命令使 JDB 程序在當前 VM 上使用任何聯結器等待(VM 在當前執行的埠)。

\>jdb –listenany

-tclient

以下命令在 Java Hotspot(™) VM(客戶端)中執行應用程式。

\>jdb –tclient

-tserver

以下命令在 Java Hotspot(™) VM(伺服器)中執行應用程式。

\>jdb -tserver

JDB - 會話

本章介紹如何以不同的方式啟動 JDB 會話。JDB 啟動是啟動 JDB 會話的常用技術。

有兩種不同的方法可以啟動 JDB 會話

  • 透過向其中新增類(主類名)來啟動 JDB 會話。
  • 將 JDB 新增到正在執行的 JVM 以啟動會話。

透過新增類啟動會話

以下命令啟動 JDB 會話

語法

\>jdb <classname>

示例

假設我們有一個名為TestClass的類。以下命令從 TestClass 啟動 JDB 會話。

\>jdb TestClass

如果您遵循此命令,它將使用任何指定的引數啟動一個新的 Java VM。然後它載入類並在執行類的第一個語句之前停止它。

透過將 JDB 新增到正在執行的 JVM 啟動會話

下面是透過將 JDB 新增到正在執行的 JVM 啟動 JDB 會話的語法和示例。

語法

以下語法適用於 JDB 會話

-agentlib:jdwp=transport=dt_shmem,address=,server=y,suspend=n

示例

假設主類名是TestClass,並且 JVM 允許 JDB 稍後連線它。以下是將 JDB 新增到 JVM 的命令

\>java
-agentlib:jdwp=transport=dt_shmem,address=jdbconn,server=y,suspend=n TestClass

現在您可以使用以下命令將 JDB 附加到 JVM

\> jdb -attach jdbconn

注意:此處,TestClass未新增到 JDB 命令中,因為 JDB 連線到正在執行的 VM 而不是啟動一個新的 VM。

JDB - 基本命令

本章將引導您瞭解 JDB 的基本命令。啟動會話後,這些命令用於除錯程式。

以下是用於除錯的命令列表。

名稱 描述
help 或 ? 最重要的JDB命令;它顯示已識別命令的列表以及簡要說明。
run 在啟動JDB並設定必要的斷點後,您可以使用此命令啟動執行並除錯應用程式。
cont 在斷點、異常或單步執行後繼續執行除錯的應用程式。
print 顯示 Java 物件和基本值。
dump 對於基本值,此命令與 print 相同。對於物件,它會列印物件中定義的每個欄位的當前值。包括靜態和例項欄位。
threads 列出當前正在執行的執行緒。
thread 選擇一個執行緒作為當前執行緒。
where 轉儲當前執行緒的堆疊。

示例

讓我們假設對於以下示例,我們有一個名為**Add**的示例類

Add.java

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

使用以下命令編譯此類 Add.java

\>javac Add.java

Run

此命令執行主類檔案,該檔案已新增到 JDB 以進行除錯。執行以下命令以執行 Add 類。

\>jdb Add
initializing jdb …
>run

執行這些命令後,您將看到以下輸出

Basic Commands

JDB - 斷點

本章介紹斷點的概念以及如何在程式中設定斷點。斷點在除錯期間會在程式執行的特定程式碼行處引入顯式停止或暫停。它有助於在程式執行過程中獲取有關程式中變數的知識。

語法

以下命令在特定行號處設定斷點

> stop at <class name>:<Line no>

以下命令在特定方法或特定變數上設定斷點

> stop in <class name>:< Method name | Variable name>

示例

以下示例演示如何在類中設定斷點。

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

將以上檔案儲存為 Add.java。使用以下命令編譯此檔案

\>javac Add.java

除錯

讓我們以除錯為例。在這裡,我們透過在 main() 上設定斷點來啟動除錯過程。以下是除錯過程中需要遵循的步驟

步驟 1:啟動 JDB 會話

以下命令在 Add 類上啟動 JDB 會話以進行除錯

\> jdb Add

步驟 2:設定斷點

以下命令在 Add 類的 main() 方法上設定斷點。

> stop in Add.main

如果斷點設定成功,您將看到以下輸出

Deferring breakpoint Add.main.
It will set after the class is loaded.
>

步驟 3:開始除錯

以下命令開始執行類 Add

> run Add

如果執行此命令,您將看到以下輸出。在此輸出中,您會發現執行在斷點位置停止,即在 main() 函式處。

Breakpoints

執行在 main 方法的第一行停止,即在“int a=5, b=6;”或程式碼中的第 11 行。您可以在輸出中觀察到此資訊。

步驟 4:繼續執行

以下命令繼續程式執行

cont

它為您提供其餘的執行部分和輸出,如下所示

> Add:11
The application exited
\>

JDB - 單步執行

本章介紹如何在除錯程式中使用單步執行的概念。單步執行是偵錯程式功能,允許您逐行執行程式碼。使用此功能,您可以檢查程式碼的每一行以確保它們按預期執行。

以下命令用於單步執行過程

  • step:單步執行到下一行
  • list:檢查您在程式碼中的位置
  • cont:繼續執行剩餘部分

示例

以下示例使用我們在上一章中使用的 Add 類

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

將以上檔案儲存為 Add.java。使用以下命令編譯此檔案

\>javac Add.java

讓我們假設斷點已設定在 Add 類的 main() 方法上。以下步驟演示如何在 Add 類中應用單步執行。

步驟 1:執行作業

以下命令開始執行名為 Add 的類。

> run Add

如果執行此命令,您將看到以下輸出。在此輸出中,您可以發現執行在斷點位置停止,即在 main() 方法處。

Stepping1

執行在 main 方法的第一行停止,即在“int a=5, b=6;”或程式碼中的第 11 行。您可以在輸出中觀察到此資訊。

步驟 2:單步執行程式碼

以下命令將執行單步執行到下一行。

main[1] step

現在執行單步執行到第 12 行。您將看到以下輸出。

Stepping2

步驟 3:列出程式碼

以下命令列出程式碼

main[1] list

您將獲得以下輸出。list 命令用於讓您知道程式控制已到達的程式碼行。請注意以下螢幕截圖中的箭頭標記=>,它顯示了程式控制的當前位置。

Stepping3

步驟 4:繼續執行

以下命令繼續執行程式碼

main[1] cont

此命令繼續執行程式碼的其餘行。輸出如下所示

> Add:11
The application exited
\>

通常,單步執行有三種類型

  • Step Into(步入)
  • Step Over(步過)
  • Step Out(步出)

Step Into(步入)

使用此命令,您可以單步執行到程式碼的下一行。如果程式碼的下一行是函式呼叫,則它會透過將控制驅動到函式的頂行來進入該函式。

在以下程式碼中,箭頭標記定義了程式碼中的控制器。

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      -> Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

如果使用**step into**命令,控制器將移動到下一行,即“int c = ob.addition(a,b);”。在此行中,有一個函式呼叫**addition(int, int)**,因此控制器將移動到 addition 函式的最頂行,箭頭標記如下所示

public class Add
{
   public int addition( int x, int y)
   -> {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      int c = ob.addition(a,b);
   System.out.println("Add: "+c);
   }
}

Step Over(步過)

Step Over 也執行下一行。但是,如果下一行是函式呼叫,它會在後臺執行該函式並返回結果。

讓我們舉個例子。在以下程式碼中,箭頭標記定義了程式碼中的控制。

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      -> Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

如果使用**step over**命令,控制器將移動到下一行,即“int c = ob.addition(a,b);”。在此行中,有一個函式呼叫**addition(int, int)**,因此函式執行在後臺完成,結果將返回到當前行,箭頭標記如下所示

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      -> int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

Step Out(步出)

Step Out 執行下一行。如果下一行是函式呼叫,它會跳過該呼叫,並且函式執行將繼續執行程式碼的其餘行。

讓我們舉個例子。在以下程式碼中,箭頭標記定義了程式碼中的控制器。

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      -> Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

如果使用**step out**命令,控制器將移動到下一行,即“int c = ob.addition(a,b);”。在此行中,有一個函式呼叫**addition(int, int)**,因此函式執行被跳過,其餘執行將繼續執行,箭頭標記如下所示

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      -> int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

JDB - 異常

本章介紹如何使用 JDB 處理異常類。通常,每當程式引發沒有 catch 語句的異常時,VM 都會列印異常行、異常原因並退出。如果異常已使用 catch 語句引發,則異常將由 catch 語句處理。在這裡,VM 會列印帶有異常原因的輸出。

當引發異常的類在 JDB 下執行時,它也會丟擲**未捕獲的**異常。可以使用**catch**命令處理該異常。

示例

讓我們以 JdbException 類為例

public class JdbException
{
   public static void main(String ar[]) throws Exception
   {
      int a=8, b=0;
      System.out.println("Welcome");
      System.out.println("Ex: "+(a/b));
   }
}

將以上檔案儲存為 JdbException.java。使用以下命令編譯此檔案

\>javac JdbException.java

按照以下步驟處理異常。

步驟 1:執行類

以下命令執行名為**JdbException**的類,如下所示

\>jdb JdbException
>run

此**JdbException**類包含異常,因此您將看到以下輸出

Exception1

步驟 2:捕獲異常

以下命令捕獲異常

mian[1] catch java.lang.ArithmeticException

它將為您提供以下輸出

Set all java.lang.ArithmeticException

步驟 3:繼續執行

以下命令繼續執行。現在 catch 處理算術異常,如下所示

Exception2

JDB - 在 Eclipse 中

本章介紹如何在 Eclipse 中使用 JDB。在繼續之前,您需要安裝 Eclipse Indigo。請按照以下步驟在您的系統上安裝 Eclipse Indigo。

步驟 1:下載並安裝 Eclipse

您可以從以下連結下載 Eclipse:http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigosr2

步驟 2:建立新專案和新類

  • 按照**檔案 -> 新建 -> Java 專案**選項建立新的 Java 專案。
  • 將其命名為**“sampledebug”**。
  • 右鍵單擊**samplebebug**專案建立新類。
  • 選擇**選項 -> 新建 -> 類**
  • 將其命名為**“Add.java”**

Add.java

public class Add
{
   public int addition( int x, int y)
   {
      int z = x+y;
      return z;
   }
   public static void main( String ar[ ] )
   {
      int a = 5, b = 6;
      Add ob = new Add();
      int c = ob.addition(a,b);
      System.out.println("Add: "+c);
   }
}

步驟 3:開啟除錯透檢視

按照以下說明開啟除錯透檢視。

在 Eclipse IDE 上,轉到**視窗 -> 開啟透檢視 -> 除錯**。現在您將獲得程式 Add.java 的除錯透檢視。您將看到以下視窗。

Debug Perspective

除錯透檢視中的部分

除錯透檢視中的部分如下所示

編碼部分

此部分顯示 Java 程式碼。這是您要除錯的程式碼,即**Add.java**。在這裡,我們可以透過雙擊程式碼行前面的位置在該行上新增斷點。您會發現帶有箭頭符號的藍色圓圈來指出該行的斷點。請參閱以下螢幕截圖;您可以找到用紅色圓圈標記的選定區域“1”。

  1. 在此處雙擊。您可以為該行設定斷點。
Code Section

斷點部分

此部分定義了設定為程式程式碼的斷點列表。在這裡,我們可以新增、刪除、查詢和管理斷點。以下螢幕截圖顯示了斷點部分。

Breakpoint Section

觀察給定螢幕截圖中的以下選項

  1. 使用左側的複選框,我們可以選擇或取消選擇斷點。在這裡,我們使用一個斷點,即 Add 類-main() 方法。

  2. 單個叉子圖示“X”用於刪除選定的斷點。

  3. 雙叉子圖示“XX”用於刪除程式碼中的所有斷點。

  4. 箭頭指標用於指向應用選定斷點的程式碼。

斷點部分中的其餘功能如下所示

  • 命中次數:它顯示控制到達此斷點的次數。它用於遞迴邏輯。

  • 掛起執行緒:我們可以透過選擇它來掛起當前執行緒。

  • 掛起 VM:我們可以透過選擇它來掛起 VM。

除錯部分

此部分用於除錯過程。它包含除錯中使用的選項。

開始除錯:請按照以下說明開始除錯。

右鍵單擊程式碼 ->單擊作為除錯 ->單擊1 Java 應用程式

除錯過程開始,如下面的螢幕截圖所示。它包含一些選定的選項,使用數字突出顯示。

  1. 我們在 Add 類 main() 方法上應用了斷點。當我們開始除錯時,控制器將停留在 main() 方法的第一行。

  2. 用於恢復除錯過程並跳過當前斷點。其工作方式類似於 JDB 命令列中的cont命令。

  3. 用於停止除錯過程。

  4. 其工作方式類似於 JDB 命令列中的step in過程。用於將控制權移至下一行,即點“1”移至下一行。

  5. 其工作方式類似於 JDB 命令列中的step over過程。

  6. 用於檢視斷點應用在哪一行。

Debug Section

按照給定的步驟和部分在 eclipse IDE 中除錯程式碼。預設情況下,每個 IDE 都包含此除錯過程。

廣告