使用jdb对tomcat进行远程调试

在工作中,经常遇到项目在生产系统遇到问题,而在测试环境或者开发环境不能复现,这时候一个重要的方法就是要在生产系统进行调试,这里调试分为两种:

  1. 使用开发工具(eclipse)进行远程调试;
  2. 使用jdb进行远程调试,或服务器(生产系统)端调试;

首先介绍一下jdb,jdb即java debugger,是随jdk发布的java命令行调试工具,什么情况下需要用jdb工具进行调试呢?比如,客户不在本地,或者没有条件赶赴客户现场,客户现场只能提供一个远程桌面环境(如:teamview获取qq远程),这样就不能将开放工具连接到生产系统,只能通过jdb这样的命令行调试工具。

以上两种调试方式,不管采用哪一种,都需要在tomcat的启动脚本中设置JVM虚拟机参数,以便是tomcat JVM虚拟机工作在debug模式:

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

或者:

-Xdebug -Xrunjdwp,transport=dt_socket,server=y,address=5432,suspend=n,onthrow=java.io.IOException,launch=/sbin/echo

transport指定了调试数据的传送方式,dt_socket是指用SOCKET模式,另有dt_shmem指用共享内存方式,其中,dt_shmem只适用于Windows平台(windows平台使用jdb调试时,只能用dt_shmem方式,用eclipse远程调试则不限)。 
server参数是指是否支持在server模式的VM中. 
onthrow指明,当产生该类型的Exception时,JVM就会中断下来,进行调式。该参数可选。 
launch指明,当JVM被中断下来时,执行的可执行程序。该参数可选 
suspend指明,是否在调试客户端建立起来后,再执行JVM。 
onuncaught(=y或n)指明出现uncaught exception 后,是否中断JVM的执行. 
虚拟机参数设置 
  1.启用调试服务 
    -Xdebug 启用调试 
    -Xrunjdwp:<sub-options> 加载JVM的JPDA参考实现库 
  2.Xrunjdwp子参数(sub-options)配置 
    Xrunjdwp子参数的配置格式如下 
    -Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]... 

  几个例子 
  -Xrunjdwp:transport=dt_socket,server=y,address=8000 
  在8000端口监听Socket连接,挂起VM并且不加载运行主函数直到调试请求到达 
  -Xrunjdwp:transport=dt_shmem,server=y,suspend=n 
  选择一个可用的共享内存(因为没有指address)并监听该内存连接,同时加载运行主函数 
  -Xrunjdwp:transport=dt_socket,address=myhost:8000 
  连接到myhost:8000提供的调试服务(server=n,以调试客户端存在),挂起VM并且不加载运行主函数 
  -Xrunjdwp:transport=dt_shmem,address=mysharedmemory 
  通过共享内存的方式连接到调试服务,挂起VM并且不加载运行主函数 
  -Xrunjdwp:transport=dt_socket,server=y,address=8000, 
  onthrow=java.io.IOException,launch=/usr/local/bin/debugstub 
  等待java.io.IOException被抛出,然后挂起VM并监听8000端口连接,在接到调试请求后以命令/usr/local/bin/debugstub dt_socket myhost:8000执行 
  -Xrunjdwp:transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe 
  等待一个RuntimeException被抛出,然后挂起VM并监听一个可用的共享内存,在接到调试请求后以命令d:\bin\debugstub.exe dt_shmem <address>执行,<address>是可用的共享内存 

对于tomcat来说,以上参数不用设置,因为tomcat的启动脚本里都已经设置好了,我们只需要使用启动脚本,并指定脚本的启动参数,就可以让TOMCT已DEBUG模式启动:

./catalina.sh jpda start;tail -f ../logs/catalina.out

启动后,tomcat进程会在8000端口监听调试程序。

启动JDB调试

jdb [ options ] [ class ] [ arguments ]

对于使用jdb进行远程调试,这里只介绍jdb的基本用法,命令格式如下:

jdb -attach ip:port -sourcepath <dir1:dir2....>

-attach 指要挂接到一个已经存在的JVM进程上

ip是远程(或本地)JVM所在服务器的ip,如果是本地,可以省略此参数;

port,即JVM启动参数中,address参数指定的端口;

--sourcepaht 可以指定多个源代码根路径,如果不指定,则默认是.

此命令执行完,正常情况会挂载到指定的JVM,并进入jdb提示符:

root@ausun:~# jdb -attach 192.168.0.172:8000
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...

可以开始输入jdb命令,主要命令如下:

设置断点

stop at MyClass:22 (在MyClass第22行源代码的第一个指令处设置一个断点)

stop in java.lang.String.length (在java.lang.String.length方法的开始位置设置一个断点)

stop in MyClass.<init> (<init>标识MyClass的构造函数)

stop in MyClass.<clinit> (<clinit>标识MyClass的静态初始化代码)

clear MyClass:45 清除断点,也可以用不指定参数的clear命令,清除之前设置的所有断点。

步进

step 命令用于向前执行到当前栈帧或被被调用方法的下一行

next 命令用于向前执行到当前栈帧的下一行。

  cont 继续运行,跳到下一个断点,或者运行下去。

猜你喜欢

转载自blog.csdn.net/p312011150/article/details/82014257