調試目标程式:Main.java,為了友善調試,運作以下指令:
C:\Users\Eugene\Desktop\studio\java>javac -g -d bin src\Main.java
最終目錄結構如下:
C:\Users\Eugene\Desktop\studio\java>tree /F
Folder PATH listing
Volume serial number is 00000200 7E94:96E4
C:.
├─bin
│ Main.class
│ Test.class
│
└─src
Main.java
1.遠端調試:
環境:vmware裡運作java程式,虛拟機IP: 192.168.80.132,實體機使用jdb調試虛拟機裡的程式:
目标程式尚未運作,則在虛拟機上運作:
C:\Users\Eugene\Desktop\studio\java>java -agentlib:jdwp=transport=dt_socket,serv
er=y,address=8000,suspend=y -cp bin\ Main
Listening for transport dt_socket at address: 8000 //這行内容是虛拟機啟動後輸出
-agentlib:jdwp=transport=dt_socket 以TCP協定作為連接配接調試端和被調試斷的媒介;
server=y,address=8000 指明java虛拟機以被調試端方式啟動,并在8000端口上偵聽;
suspend=y java虛拟機啟動後并不馬上運作程式,而是将它挂起,直到調試器連上。
實體機上運作:
C:\Users\Eugene>jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.80.132,port=8000
設定未捕獲的java.lang.Throwable
設定延遲的未捕獲的java.lang.Throwable
正在初始化jdb...
>
VM 已啟動: 目前調用堆棧上沒有幀
main[1] stop at Main:32
正在延遲斷點Main:32。
将在加載類後設定。
main[1] use C:\Users\Eugene\Desktop\studio\java\src\main.java
main[1] run
2.Attach運作中的程式:
如果目标程式已經在運作中,并且并沒有以"-agentlib:jdwp=transport=dt_socket"的形式啟動,這時需要以Attach的形式調試程式。(示例中的指令适用于本地調試)
首先模拟正在運作的程式,該程序的PID=1824:
C:\Users\Eugene\Desktop\studio\java>java -cp bin Main
Enter a Char:
啟動jsadebugd daemon,并attach到目标程式:
C:\Users\Eugene>jsadebugd 1824
Attaching to process ID 1824 and starting RMI services, please wait...
Debugger attached and RMI services started.
啟動jdb連接配接jsadebugd:
C:\Users\Eugene>jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector
:debugServerName=localhost
Initializing jdb ...
> use C:\Users\Eugene\Desktop\studio\java\src\main.java
Command 'stop' is not supported on a read-only VM connection
> where all
Attach Listener:
Signal Dispatcher:
Finalizer:
[1] java.lang.Object.wait (native method)
[2] java.lang.ref.ReferenceQueue.remove (null)
[3] java.lang.ref.ReferenceQueue.remove (null)
[4] java.lang.ref.Finalizer$FinalizerThread.run (null)
Reference Handler:
[1] java.lang.Object.wait (native method)
[2] java.lang.Object.wait (Object.java:503)
[3] java.lang.ref.Reference$ReferenceHandler.run (null)
main:
[1] java.io.FileInputStream.readBytes (native method)
[2] java.io.FileInputStream.read (null)
[3] java.io.BufferedInputStream.fill (null)
[4] java.io.BufferedInputStream.read (null)
[5] Main.main (Main.java:34)
> quit
3.啟動HSDB,觀察運作中的java程式:
C:\Users\Eugene>java -cp "%JAVA_HOME%\lib\sa-jdi.jar" sun.jvm.hotspot.HSDB
HSDB啟動後點選:File-Attach to Hotspot process",并在彈出對話框中輸入目标程序的PID。
附注:有部分JDK版本在attach目标程序時會失敗,并報錯:找不到sawindbg.dll。這時需要将%JAVA_HOME%\jre\bin\sawindbg.dll拷貝到與jdk同一目錄的jre\bin下。