【IT168 专稿】调试的方法虽然千千万万,但归根结底,就是找到引发错误的代码。Eclipse调试器的目标是让程序员能对本地或远程程序进行错误侦测与诊断。该调试器提供所有标准调试功能,包括进行单步执行、设置断点和值、检查变量和值以及暂挂和恢复线程的能力。这篇文章主要讲述Eclipse调试器,包括Debug视图,断点的设置,Java代码的调试等等。与一些理论性较强的文章相比,本文更注重实践,为读者提供更加使用的调试技巧。

  Eclipse 调试器

  Eclipse 平台的最大特色是插件化(Plugin)。调试是任何程序员都无法回避的工作。因此Eclipse的内置插件Java开发工具包(Java Development Toolkit,简称JDT)中集成了一个功能强大的Java调试器(Debugger)。实际上,JDT是Eclipse工作平台(Eclipse Platform Workbench)的基础工具,除了调试器,还提供透视图、视图、编辑器、搜索等Eclipse基础功能。

  由于Eclipse调试器采用了基于客户端/服务器的设计模式,远程应用的调试变得与本地一样简单。其工作原理是,本地Eclipse工作平台充当调试的客户端,而远程应用所在的机器则充当了调试服务器的角色。

  Debug 视图

  Debug视图作为Eclipse调试器透视图的一部分,管理与程序调试相关的功能。如图所示,Debug视图呈树状结构,每一个线程对应一树节点。图中显示的是暂挂线程Main的调试堆栈帧结构。

  作为标准的Java调试平台,Debug视图提供了许多执行控制命令(Execution Control Commands),用于在程序中设置/取消断点,单步执行,暂挂与恢复线程。以下是一些常用的执行控制命令:

  1. Layout布局

  Debug视图的布局与断点调试等主体功能相比,显得并不那么乍眼,因此也常被人忽略,不过Eclipse的魅力之一就是它的细节做的特别完美。我们简单介绍一下Debug视图布局的特点,如图所示。

  第一个特点是Automatic功能。选择菜单选项Layout -> Automatic,可以实现Debug视图在树状模式与Breadrumb模式之间的自动互换。相信很多编程人员都喜欢Breadrumb模式,向面包片一样,一层一层的,直观,醒目。

  Layout菜单的第二个特点Breadrumb模式。选择菜单选项Layout -> Breadcrumb,打开Breadrumb模式。除此之外,选择菜单选项Layout -> Auto-Expand Breadcrumb,可实现自动展开Breadrumb模式。当选择下拉框时,可自动定位到暂挂线程的调试堆栈帧。这个细节对于编程人员来说,也是非常的方便。

  2. 调试启动停止等相关命令

  Debug视图提供了诸多的启停控制命令,叫法上与其它的调试器可能稍微有些不同,具体如下:

  启动调试视图:Eclipse提供三种方式来启动程序(Launch)的调试,分别是通过菜单(Run –> Debug)、图标(“绿色臭虫”)以及快捷键(F11),在这一点上,与其他命令(例如Run)类似。

  停止调试:Eclipse通过Terminate命令终止对本地程序的调试。特别的,对于远程程序的调试,Eclipse使用Disconnect命令来终止与远程JVM的socket连接。前面我们谈到,Eclipse调试器采用了基于客户端/服务器的设计模式,本地Eclipse工作平台充当调试的客户端,而远程应用所在的JVM则充当了调试服务器的角色。简单的说,Terminate命令终止本地调试,Disconnect命令终止远程调试。Terminate/Disconnect All终止所有的调试,包括本地与远程。

  重新启动调试:Eclipse通过Relaunch命令重新启动调试。这里需要指出的是Relaunch支持两种重启动模式,一种是针对已经停止的程序调试,另一种是针对Active的当程序调试。前者不难理解,效果上等同于Terminate+Launch。后者的处理方式有些不同,效果上则等同于Launch一个新的Debug项。实际上,针对后一种情况,我们通常采用Eclipse的Terminate and Relaunch命令来达到重启Debug的目的。

  删除调试项:Eclipse支持针对多个程序的调试。我们称每一项对应一个Debug Item。Remove命令将某一个Debug Item从当前的Debug视图中删除。不过,Remove命令只适用于已停止的Debug Item,而对于运行中的Debug Item,Eclipse提供了Terminate and Remove命令。假如想停止并清除所有的Debug Item,则可以通过Terminate and Remove All命令。此外,Eclipse还提供了Copy Stack命令或者快捷键Ctr+C,可将调试堆栈帧内容拷贝至剪贴板中,这样效果上就等同于“撤销”。

  以上这些命令虽然有些琐碎,但是非常能反映Eclipse对细节的把握与控制。

  3. 单步执行

  相信任何调试人员对单步调试非常的熟悉。Eclipse提供step into、step over、 step return三个命令来支持单步调试。三者的具体区别是:step into(快捷键F5)就是单步执行,遇到子函数就进入并且继续单步执行;step over(快捷键F6)是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。step return(快捷键F7)就是单步执行到子函数内时,用step return就可以执行完子函数余下部分,并返回到上一层函数。说的通俗点就是,step into:进入子函数,step over:越过子函数,但子函数会执行,step return:跳出子函数。

  此外,Eclipse还提供了Run to line(快捷键Ctr + R)功能,从开始处运行程序,到正在执行的断点暂停。

  4. Drop to Frame

  Drop to Frame功能虽然不属于单步调试的核心,但是该功能非常的适用,它为调试人员提供了调试回退的机会。Drop to Frame可以重新跳到当前方法的开始处重新执行,并且所有上下文变量的值也相应回到初始时刻,如图所示。

  5. Step Filters

  当在你调试的时候,你只希望查看自己的代码,而不是从JDK或者是其他库中的代码,甚至是你也想屏蔽自己代码库中的框架部分代码。

  针对这样的需求,Eclipse提供了逐步过滤器(Step Filters)选项指的是一直执行直到遇到未经过滤的位置或断点。Step Filters功能由Use Step Filters,Edit Step Filters,Filter Type,Filter Package四项组成。

  具体操作如下:

  步骤 1: Windows -> Preferences -> Java -> Debug -> Step Filtering.

  步骤 2:选择‘Use Step Filters’.

  步骤 3:在屏幕上选中所需的选项。你可以添加你自己代码库中的部分代码。

  步骤 4:点击‘Apply’.

  原理上,Edit Step Filter命令用于配置Step Filter规则,而Filter Type与Filter Package分别指的是过滤的Java类型与Java Package,如图所示。

  6. 声明选项

  Open Declared Type命令会打开当前调试堆栈帧的类型声明编辑器。而Open Declared Type Hierarchy则展现的是完整的层次结构,如图所示。

  7. 线程的暂挂/恢复

  Eclipse通过Suspend与Resume来支持线程的暂挂与恢复。一般来讲,Suspend适用于多线程程序的调试,当需要查看某一个线程的堆栈帧及变量值时,我们可以通过Suspend命令将该线程暂挂。Resume用于恢复。有两种Resume需要注意:第一是当在调试过程中修改程序代码,然后保存,点击Resume,此时程序会暂挂于断点。第二是当程序抛出异常时,运行Resume,程序也会暂挂于断点。

  8. Show Monitor命令

  Show Monitor命令可实时显示变量的值。举个例子,我们写一个简单的HelloWorld程序。

  /**

  * Hello World

  */

public class HelloWorld {

  public static void main(String[] args) {

  Line 11: Object mutex = new Object();

  synchronized (mutex) {

  System.out.println("Hello World!");

  }

  }

  }

  如图所示,Show Monitor对应的监视信息会以“钥匙”的形式出现在当前stack frame前面。当前信号量的id为16。

 

    需要指出的是,不是所有的JVM都支持Show Monitor功能。如果是IBM或者是Oracle的JVM,则要求版本高于1.4,否则提示的是Alert信息:VM does not provide monitor information,如图所示。

  调试选项配置

  在调试程序之前,需要预先完整地编译和运行代码,创建运行配置并确认其正常启动。举个例子,假设我们需要调试一个HelloWorld的Java Application程序。我们需要如下步骤:

  1. 选择菜单 Run --> Open Run Dialog ,打开Run对话框。在对话框左侧的类型列表中选中Java Application,右键 --> New ,新建一个Java Application运行配置HelloWorld,如下图所示。

  根据目标程序的类型,Eclipse提供了如下几种类型调试。Eclipse Application主要针对Eclipse插件本身的调试,Java Applet针对Java浏览器小程序的调试,Java Application针对Main函数为如何的Java应用程序,JUnit/JUnit Plug-in Test针对的是基于JUnit框架的单元测试程序的调试,OSGi Framework针对的是基于OSGi框架的程序调试,所谓OSGi 框架指的是提供一个安全的可管理的Java Framework来部署可扩展的Java服务。而Remote Java Application针对的是远程应用程序的调试。

  2. 配置项目和启动类。在运行配置HelloWorld的Main Tab页,指定Project为导入的Test项目,启动类为HelloWorld,如下图所示。其中Main class提供了一个选项,即过滤系统库中的Main函数。

  3. 在运行配置HelloWorld的Arguments Tab页配置系统属性、类加载路径和工作目录。Argument分两部分,即Program arguments与VM argument。Program arguments指的是程序所需的参数,由main函数的args[]参数传入至程序。VM Arguments是设置虚拟机的属性。假设我们对Test类设置的Program arguments为pro1 pro2 pro3,而VM arguments设置为-DsysProp1=sp1 -DsysProp2=sp2。那么当点击Run按钮运行Java Application,完整的命令应该为java -DsysProp1=sp1 -DsysProp2=sp2 Test pro1 pro2 pro3。这里我们不需要指定任何参数。保留空白。

  4. 选择JRE Tab。Eclipse提供了三种Java运行时选项。分别为Project JRE,Execution enviroment, Alertnate JRE。我们选的是第三种,版本为JDK1.6。

  5. Classpath Tab配置类加载路径。类路径可以连接 Java 运行库和文件系统。它定义编译器和解释器应该在何处查找要加载的 .class 文件。它的基本思想是:文件系统的层次结构反映了 Java 包的层次结构,而类路径则定义了文件系统中的哪个目录可以作为 Java 包层次结构的根。这里我们采取默认方式。

  6. 在Source Tab配置源文件查看路径。通过右边的Add按钮可以从许多地方(包括文件系统、既存项目等)添加源文件查看路径项。如果我们在调试需要深入到JDK中,可以通过该Tab添加源代码。这里配置我们采取默认方式。

  7. Environment Tab设置环境变量。我们采取默认方式。

  8. Common Tab设置常见的选项,如编码等。

  调试Java

  毫无疑问,最常见的调试过程就是设置断点,以允许检查在条件语句和循环中的变量和值。要在 Java 透视图的 Package Explorer 视图中设置断点,双击所选的源代码文件,在编辑器中打开它。遍历全部代码,将光标放置在含有可疑代码的那一行的标记栏上(在编辑器区域的左侧)。双击以设置断点。

  断点类型

  Breakpoints视图列出当前工作区别设置的所有断点,如图所示。按照功能分又可分为:

  Java Class Load Breakpoints:当load指定的class时发生。这个在调试class load非常有用。

  Java Exception Breakpoints:当发生异常时发生暂挂。如图,Choose an exception支持占位符*与?。占位符*表示任何字符串,?表示任意一个字符。可以根据需要决定在出现异常的时候是否暂挂当前线程。

  Java Line Breakpoints:Java行断点。这是最普通的断点形式。即双击程序中某一行最左边区域,添加一个行断点。

  Java Method Breakpoints:Java方法断点。方法断点就是将断点打在方法的入口处,如下图。方法断点的特别之处在于它可以打在 JDK的源码里,由于 JDK 在编译时去掉了调试信息,所以普通断点是不能打到里面的,但是方法断点却可以,可以通过这种方法查看方法的调用栈。

  Java Watch Breakpoints:Java变量监视断点,实时地监视变量的变化

  断点属性

  Hit count:选择breakpoint view->右键hit count。设置执行次数,适合调试程序中的for循环。当循环中达到指定次数,则暂挂该线程或者虚拟机本身。

  条件断点:断点大家都比较熟悉,在Eclipse Java 编辑区的行头双击就会得到一个断点,代码会运行到此处时停止。条件断点,顾名思义就是一个有一定条件的断点,只有满足了用户设置的条件,代码才会在运行到断点处时停止。在断点处点击鼠标右键,选择最后一个"Breakpoint Properties"。条件断点的条件一般来说有两种类型,一种是boolean变量为真,另一种是当侦测到变量值改变。

  断点的导入与导出:这这对于调试大型工程非常有帮助。既可以导入导出所有的断点,也可以加以选择。导出文件的后缀为.bkpt。

  变量属性

  查看变量:Variables 视图(在 Display 窗口中)显示了选中的堆栈帧中的变量值。要查看所请求的变量,只需展开 Variables 视图中的树直到所请求的元素为止。

  改变变量值:Variables 视图不仅能查看变量,而且能够改变变量的值。如果您也碰到下面的问题,建议使用改变量值。即当代码停在了断点处,但是传过来的值不正确,如何修改一下变量值保证代码继续走正确的流程,或是说有一个异常分支老是进不去,能不能调试时改一下条件,看一下异常分支代码是否正确?

  表达式属性

  要在 Debug 透视图的编辑器中求表达式的值,选中设置有断点的一整行,并在上下文菜单中选择 Inspect 选项。表达式是在当前堆栈帧的上下文中求值的,其结果显示在 Display 窗口的 Expressions 视图中。

  Eclipse 提供了内置的 Java 调试器,具有标准调试功能,包括进行单步执行、设置断点和值、检查变量和值、暂挂和恢复线程的能力。Eclipse同时也是一个可支持许多其它语言的可扩展平台,而其中最重要的就是支持 C/C++。Eclispe官方网站:http://www.eclipse.org

Eclipse Debug的更多相关文章

  1. eclipse debug 过滤一些包

    eclipse debug java程序的时候, 我们按F5的时候,常常会进入java自带类库里,这些类库并不是我们需要debug的代码,这样会影响debug的效率,我们可以在eclipse里设置,过 ...

  2. eclipse debug (调试) 学习心得

    eclipse debug (调试) 学习心得   进入debug模式:   1.设置断点   2.启动servers端的debug模式   3.运行程序,在后台遇到断点时,进入debug调试状态   ...

  3. Eclipse debug调试

    Eclipse debug调试: F5:跳入方法F6:向下逐行调试F7:跳出方法F8:直接跳转到下一个断点

  4. 转:Eclipse Debug 界面应用详解——Eclipse Debug不为人知的秘密

    今天浏览csdn,发现一文详细的描述了Eclipse Debug中的各个知识点,非常详尽!特此记录. Eclipse Debug不为人知的秘密 http://blog.csdn.net/mgoann/ ...

  5. Eclipse Debug不能热部署解决

    摘要: Eclipse Debug不能热部署代码may be out-of-synch 问题描述:Project通过ant工具编译部署到JBoss下,在使用Eclipse远程调试功...       ...

  6. eclipse debug模式

    eclipse debug模式 1.怎样在Eclipse中设置断点 方法/步骤 1 首先打开工程项目 2 第一种是,把鼠标移动想要设置断点的行,在行号前面空白地方双击,就会出现断点 3 第二种是,在菜 ...

  7. eclipse debug 执行到断点处并没有停下,断点无效问题

    转自:http://blog.csdn.net/cuidiwhere/article/details/14434439 现象: 利用eclipse debug时,执行到断点处并没有停下.正常情况下,在 ...

  8. eclipse debug Liunx服务器上的svn项目

    1.本地项目提交到svn上,以保证本地代码与服务器代码相同 2.开启服务器debug端口 3.使用root账号重新部署服务器项目并监听catalina.out sh /home/p/deploy/gt ...

  9. Eclipse debug模式 总是进入processWorkerExit

      Eclipse debug模式 总是进入processWorkerExit CreateTime--2018年3月9日15:44:59 Author:Marydon 请移步至文章:http://w ...

  10. Eclipse debug 的 drop to frame 的技巧

    前些天和同事交流调试技巧时,知道了 Eclipse debug 时有个 drop to frame 的技巧.这是我以前不知道的,自己又查了一下这个功能的含义.官方的解释是: Select the Dr ...

随机推荐

  1. oracle常用命令大全及心得

    学习时整理的 Oracle 1.set linesize 100; 设置长度2.set pagesize 30; 设置每页显示数目3.em a.sql 打开记事本 4.@ a 执行文件a中的代码,可指 ...

  2. Time Series data 与 sequential data 的区别

    It is important to note the distinction between time series and sequential data. In both cases, the ...

  3. C#ActiveX控件开发学习

    一:C#ActiveX控件开发注意事项   1:C#开发的ActiveX控件只可在装有Framework的系统上才能用. 2:只有IE浏览器支持. 3:初次安装需要导入代码签名证书及其证书链的方式, ...

  4. gulp LiveReload middleware

    用yo搭建的angular项目,用gulp自动化构建. 自动化构建主要的功能大致有: 1. 文件压缩 2. 文件重命名 3. 文件合并 4. css,js文件自动引入到html 5. 自动刷新 ... ...

  5. TDDL DataSource

    TDDL DataSource 分为 AtomDataSource GroupDatasource 他们两者没有依赖关系, 都实现了 JDBC 规范, 可以作为独立的 datasource 单独使用 ...

  6. .NET技术大系概览 (迄今为止最全的.NET技术栈)

    从2002年的.NET 1.0开始,1.1,2.x,3.x,4.x,每个新版本的.NET都会增加新的技术,生态圈也在不断壮大. AD: 前言 .Net推出13年了,Visual Studio 2015 ...

  7. MVc Forms Membership rolemanage 角色权限验证管理

    Forms  登录验证Membership 权限验证rolemanage 角色管理 以往的项目中只有单纯的Forms 验证今天想把这三个结合到mvc 中发现要导入aspnet_ 相关表,但是有个问题验 ...

  8. jqueyr获取动态创建的元素

    javascript代码是按照代码顺序执行的,所以如果你用某个元素的click事件创建一个元素,id为test,然后在下面$("#test")是无法选择到的. 正确的方法是将在cl ...

  9. prim

    prim算法很难,但是我也把他写出来了.usaco3.1.1 #include <iostream> #include <cstring> using namespace st ...

  10. servlet总结

    什么是Servlet Tomcat容器等级 手工编写第一个Servlet 使用MyEclipse编写Servlet Servlet生命周期 Servlet常用对象,且与Jsp九大内置对象的关系 Ser ...