使用JDB进行调试

作者: weipeng2k | 来源:发表于2018-09-08 11:37 被阅读0次

       在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种。
       JDB是 The Java Debugger 的简称,它可以用来debug一个Java程序,同时它是 JPDA 的一个参考实现,只是这个实现是基于命令行的。提到命令行,有些同学心里就犯嘀咕了,离开了GUI,能debug吗?当然可以,只要熟记几个命令,在受限环境下debug不是不可能。

使用JDB的目的是,更细节的诊断和操控代码,如果只是观察值,可以使用arthas之类的工具

JPDA

       JPDA将调试过程分为两部分:被调试的程序(被调试者-debuggee)和JDI(调试者-debugger)。JDI一般为一个调试应用程序的用户接口(或Java IDE的一部分),本文中就是JDB。被调试的应用程序在后端运行,而JDI在前端运行。在前端与后端之间有一个通信通道运行JDWP(Java Debug Wire Protocol)协议,因此,被调试程序与调试器可以位于同一个系统内,也可位于不同的系统中。

jpda.png

       从开发者的角度,一个调试应用程序可进入任何JPDA层面。只要JDI基于JDWP,就可以debug任何厂商实现的JVM了,比如:j9等。
       JDWP 有两种基本的包(packet)类型:命令包(command packet)和回复包(reply packet)。
       在JDB里的例子中,我们使用JDB通过socket向本地的JVM发送JDWP请求。
       Debugger 和 target Java 虚拟机都有可能发送 command packet。Debugger 通过发送 command packet 获取 target Java 虚拟机的信息以及控制程序的执行。Target Java 虚拟机通过发送 command packet 通知 debugger 某些事件的发生,如到达断点或是产生异常。
       Reply packet 是用来回复 command packet 该命令是否执行成功,如果成功 reply packet 还有可能包含 command packet 请求的数据,比如当前的线程信息或者变量的值。从 target Java 虚拟机发送的事件消息是不需要回复的。

环境

       一般来说需要准备一个应用、代码包括数据库等,这样真实的案例才容易有感觉。这里笔者准备了一个简单的项目:https://github.com/weipeng2k/spring-guide,其中:spring-guide-spring-boot项目,可以尝试构建。
       在11.239.175.138,用docker拉起了一个mysql实例,具体的jdbc-url为:jdbc:mysql://11.239.175.138:23306/book,这个在应用中的application.properties中已经配置了。
       应用实际就提供了一个rest接口,访问:localhost:8080/api/author/1 时,会返回作者的信息。

源码

       AuthorApi是控制器,代码和准备debug的点:

code-api.png

       可以看到逻辑非常简单,就是根据Id查询作者信息,准备debug的位置在24行。
       AuthorQueryServiceImpl是服务的实现,代码和准备debug的点:

code-service.png

       服务实现就是查询DAO后,将结果返回,如果找得到则返回值,否则返回null,我们会在26行进行debug。

示例

       首先启动应用,如果要进行debug,一般都会在应用上配置对应的调试参数,包括调试的端口。

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar ~/spring-guide-spring-boot/target/spring-guide-spring-boot-1.0.0-SNAPSHOT.jar

       本例中是将调试端口开在5005。
       接下来运行jdb,连接到调试端口上进行调试。

       点击观看,操作流程。

asciicast
命令 说明
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=5005 使用jdb连接本地的调试端口,线上可以在/opt/taobao/java对应的JavaHome下找到jdb命令
stop at com.murdock.books.spring.guide.springboot.service.impl.AuthorQueryServiceImpl:26 断点打在com.murdock.books.spring.guide.springboot.service.impl.AuthorQueryServiceImpl的第26行
clear 列出所有断点
clear com.murdock.books.spring.guide.springboot.service.impl.AuthorQueryServiceImpl:26 清除对应的断点
locals 列出当前的变量,包括本地变量,参数变量等
print x 打印输出变量x
dump x dump对应的变量x
wherei 当前debug所在的线程堆栈,输出当前的堆栈
next 下一步,代码向下执行
cont 代码执行放过,继续执行,会停留在下一个断点处

相关文章

  • 使用JDB进行调试

    在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行d...

  • 使用jdb调试apk

    jdb是一个支持java代码级调试的工具,它是由java jdk提供的,存在于xxx\Java\jdk1.6.0_...

  • Android基础:jdb使用

    jdb可以用来打断点,jdb使用记录一下 一.首先找出需要调试进程的pid,adb shell ps -A 二.获...

  • JDB调试

    工具 Android Studio,后面的内容简称AS. Android Studio 是谷歌推出的一个Andro...

  • java调试

    Java 调试器(JDB)是 JDK 内置的命令行工具。从调试的指令和命令行接口两方面看的话,JDB 至少从概念上...

  • 使用JDB直接在远程服务器上进行调试

    程序开发过程中,debug 是必不可少的一部分,它能帮助我们及时发现一些不易察觉的 bug,但并不是所有的 bug...

  • Android IDA 7.0 动态调试攻略

    1.准备 a. 下载并安装 IDA 7.0版本 b.下载并安装JDK,因为需要使用jdb命令调试应用。 c.准备已...

  • 1.Tomcat使用IDEA远程Debug调试的讲解

    JAVA 支持调试功能,本身提供了一个简单的调试工具JDB,支持设置断点及线程级的调试同时,不同的JVM通过接口的...

  • java相关的

    一文让你明白Java字节码 java命令调试程序 java jdb 命令行调试程序 Java编写时钟 Applet...

  • jdb调试本地JAVA程序

    一、配置 先参考该文章对java程序启动前进行配置:eclipse远程调试Web项目和Java程序 调试步骤可参考...

网友评论

    本文标题:使用JDB进行调试

    本文链接:https://www.haomeiwen.com/subject/mvukgftx.html