天天看點

遠端調試java程式/Attach java程式/啟動HSDB

調試目标程式: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。

遠端調試java程式/Attach java程式/啟動HSDB

附注:有部分JDK版本在attach目标程序時會失敗,并報錯:找不到sawindbg.dll。這時需要将%JAVA_HOME%\jre\bin\sawindbg.dll拷貝到與jdk同一目錄的jre\bin下。