Java程序调试:启动命令解析

Java调试线协议(Java Debug Wire Protocol, JDWP) 可以用来调试Java应用(application)及小程序(applets)1

调试的目标虚拟机(VM) 进程可以是本地的,也可以位于远程服务器上。两种调试场景的实现原理是一样的,只是配置不同而已。

Oracle的VM根据命令行选项来决定是否以及如何加载JDWP agent 进行 debug2指定加载 JDWP agent 的方式有两种:

  • -agentlib:jdwp=[=],[=]...
    例如:
    -agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000

  • -Xrunjdwp:[=],[=]...
    例如:
    -Xrunjdwp:transport=dt_shmem,address=mysharedmemory

下面详细叙述启动Java调试的过程。

1 以debugging模式启动应用

要使用JDWP调试Java应用,首先需要以debugging模式启动应用(假设应用启动类名为Test):

  • 在 Oracle Solaris 及 Linux 系统上: java -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=y Test

  • 在Windows系统上:java -Xdebug -Xrunjdwp:transport=dt_shmem,address=debug,server=y,suspend=y Test

参数说明23

  • -Xdebug:运行运行时调试。必须与 -Xrunjdwp 选项配合使用,才能实现调试功能。
  • -Xrunjdwp:debug-settings:按指定的调试设置参数,开启一个JDWP会话。必须与 -Xdebug 选项配合使用,才能实现调试功能。

设置调试参数(debug-settings部分):

  • transport=transport-mechanism:指定传输机制。传输机制用作debuggee与debugger之间的通信。支持的机制包括:
    • dt_socket该机制在debugger 程序与目标VM之间使用一个流式TCP/IP连接(stream TCP/IP connection)。在该机制下,debugger 程序与目标VM可在同一台机器上,也可在不同机器上。在 Solaris、Linux 及 Microsoft Windows 平台均可使用该机制2
    • dt_shmem:即 shared memory(共享内存)。该机制利用共享内存来 debugger 程序与目标VM之间交换 JDWP 数据包。在该机制下,debugger 程序与目标VM必须位于同一台机器上。该机制仅限于 Microsoft Windows 平台。共享内存传输地址是Windows下文件映射对象(file-mapping object)的名称,可以是除了反斜杠之外的任意字符。
  • server={y|n}:启动调试代理(debug agent)作为调试的服务器端,默认为n。如果为y,则监听来自 debugger 程序的连接;否则,主动连接由上面的address指定主机端口
  • address=host:port:用作与debugger连接的传输地址。如果 host 未指定,则将 localhost 作为主机。如果 server=n,则VM会尝试连接该地址指定的debugger程序;如果server=y,则会监听该地址/端口的连接。若为server=y且没有指定address,则VM会在启动时自主选一个端口并打印在stdout上,作为debugger连接它的地址。debugger 必须与指定的端口连接上,才能进行调试。注意此端口不要与其他服务的监听端口(如Tomcat的监听端口)冲突
  • suspend={y|n}:如果设为n,则应用立即启动,debugger 在应用启动後连接上去。如果设为y,则VM启动後,不会立即加载启动应用的main class。需要等debugger 连接上前面指定的端口,并发送一个resume(重启)命令才启动。这种设置可以使调试在应用启动过程中就开始。默认为y。

应用启动完成後,可以通过ps -ef | grep java查看当前Java应用进程的启动参数,检查是否以debugging模式启动及其启动参数。例如:
在这里插入图片描述

更多参数说明见文档2中 Oracle VM Invocation Options 部分。

这样Test类以debugging模式启动,并等待debugger(调试器) 通过端口 8888 (Oracle Solaris 及 Linux 系统) 或 端口debug (Windows系统) 连上它。

2 debugger连上debugging模式的Java进程

打开一个新的命令行页面,输入下述命令运行jdb,并将其连上正在运行中的、debugging模式的Java进程:

  • 在 Oracle Solaris 及 Linux 系统上: jdb -attach 8888

  • 在Windows系统上:jdb -attach 'debug'

jdb启动并连上Java进程後,就可以执行Java-level 的调试了。

3 设置断点,进行调试

接下来设置断点,然後开始开始。比如,在Testmain方法的起始处设置一个断点:

stop in Test.main run

jdb运行到达(hit)断点时,就可以观察进程运行上下文中的变量,看是否符合预期。

关于利用JDWP进行混合 native-level 与 Java-level 的调试,以及调试 applet,请查看所附的参考资料1

参考资料


  1. Java Platform, Standard Edition Troubleshooting Guide ↩︎ ↩︎

  2. Connection and Invocation Details ↩︎ ↩︎ ↩︎ ↩︎

  3. 14.3 Emulator Command Line Options - 14.3.3 Debugging and Tracing Options ↩︎

你可能感兴趣的:(Java)