原创

工作很多年的程序员可能都不知道的Java IDE调试断点配置技巧

断点类型与配置

行断点(line breakpoints)
  • 当程序执行到断点对应代码行,程序挂起,该类型断点的图标:line breakpoint

图片

字段断点(field breakpoints)
  • 当程序访问该字段或修改该字段时,触发该断点程序挂起,该类型断点的图标: field watchpoint

图片

  • 鼠标右键点击该断点图标 ,弹出该断点配置,会有Field access和Field modification选项,此选项是字段类型断点特有的,分别对应访问该字段或修改该字段触发断点,两项同时选中,则访问与修改该字段都会触发断点。

    image-20210302143533764

方法断点(method breakpoints)
  • 该类型断点的图标: a6d0m-c0ty111111111j

图片

  • 当断点加在class类名这一行,且该类中没有编写构造函数(只有默认无参构造函数),当调用默认无参构造函数时会触发此断点,程序挂起,故该断点虽然图标是行断点类型图标,但实际上属于方法类型断点。

图片

  • 鼠标右键点击该断点图标 ,弹出该断点配置,会有EmulatedMethod entryMethod exit选项,此选项是方法类型断点特有的。Emulated勾选中,会将方法断点优化成方法中第一条和最后一条语句的行断点,这样会优化调试的性能,因此在IDE中会默认选中,但在调试native方法或者没有行号信息的远程代码时不要勾选此选项,Metthod entry表示在方法进入时触发断点 ,Method exit表示方法执行结束时触发断点。
  • 通过匹配符批量添加方法断点,在断点列表页

    111111

匹配符示例:

Class Method Result
* print 匹配所有类的print()方法
Printer * 匹配Printer 类中的所有方法
Printer set* 匹配Printer 类中的所有方法名set开头的方法
异常断点(exceptin breakpoints)
  • 异常断点分为两种,一种是Any Exception,任意Throwable异常被捕获或未被捕获就会触发断点,另一种是指定类型的异常及其该异常子类被捕获或未被捕获会触发断点,该类型断点图标exception breakpoint
  • 鼠标右键点击该断点图标 ,弹出该断点配置,会有Caught exception和Uncaught exception选项,此选项是字段类型断点特有的,Caught exception选项选中时,当指定的异常被捕获时,触发断点程序挂起,Uncaught exception选中时,当指定的异常未被捕获时,触发断点程序挂起

图片

断点通用配置

​ 断点有许多属性配置,如下图所示,下面将会对各个属性的作用以及使用进行说明。

图片

Enabled
  • 表示是否启用该断点,选中表示启用,取消选中表示不启用。
Supend
  • 当断点的Suppend属性被勾选,触发该断点时,会触发程序挂起,当该属性未选中时,程序触发该断点时,程序不会挂起,常用于输出一些表达式结果日志。
  • 当断点的All属性被勾选,触发该断点时,会挂起所有线程
  • 当断点的Thead属性被勾选,触发该断点时,只会挂起触发该断点的那个线程,不影响其他线程
Condition
  • 可以输入一段能获得true或false的表达式,程序运行到断点处,且表达式条件为true才会触发断点
Log

​ 下面三个属性选项经常配合Suppend属性一起使用,用于在不挂起的情况下,输出一些想要的日志信息

  • Breakpint hit message:控制台输出触发端点的日志信息,类似如:Breakpoint reached at ocean.Whale.main(Whale.java:5)

  • Stack trace:输出触发断点时的堆栈信息

  • Evaluate and log:计算表达式结果并输出表达式结果到控制台,表达式的计算基于断点所在行的上下文,表达式的语句可以是字符串字面量,如"我是字符串",也可以是方法调用,如users.size(),也可以是多行语句块,表达式的结果取自return语句,如果没有return语句,会取表达式中的最后一行语句。

    图片

Remove once hit
  • 是否在断点触发后移除该断点,后续不在触发
Disable until hitting the following breakpoint
  • 指定在另一个断点触发后,该断点才启用,若该断点启用后,并且被触发,触发后是否继续启用由Disable againLeave enabled指定,Disable again表示触发后不再启用,Leave enabled表示触发后继续启用。
Filters

​ IDE允许我们在调试的时候,过滤掉一些不需要的断点触发和挂起,加快调试效率,有如下几种过滤方式:

  • Catch class filters:此选项只对异常类型的断点可用,可以让程序只在指定类和子类中抛出的异常才会触发断点或者不在指定的类和子类中触发断点(即排除一些类,排除通常以-开始,例如-pacakge.ClassName),

  • Instance filters:只有指定实例id号可以触发断点,多个实例id号以空格隔开,实例id号可以在Variables和Memory面板中查看,如下图:

    图片

    图片

  • Class filters:可以让程序只在指定类和子类中才会触发断点或者不在指定的类和子类中触发断点(即排除一些类)。

  • Caller filters:根据调用者来进行过滤,需指定方法的全限定名(包含方法签名),例如`mypackage.MyObject.addString(Ljava/lang/String;)V

    示例:

    | 配置 | 说明 |
    | ------------------------------------------------------------ | ------------------------------------------------------------ |
    | -package1.Class1.method1([Ljava/lang/String;)Ljava/util/List; | 此处是caller filter的配置示例,该示例中排除了来自package1.Class1类中method1方法并并且方法签名是: List method1 (String[] input)的调用(即不触发断点) |
    | package1.Class1 *s2 -package3.Class3 | Class filterscatch class filter中的配置示例。该示例中,断点仅在package1.Class1以及全限定名以s2结尾的类中可以被触发,并且不在 package3.Class3中触发(-开头表示排除) |
    | -java.* -sun.* | Class filterscatch class filter中的配置示例,该示例排除了 java and sun包下的所有类(-`开头表示排除) |

Pass count
  • 勾选中并输入一个正整数N,N>=1,那么程序会每N次命中断点才会触发挂起,如果同时设置了conditionpass count属性,ide会优先判断condition表达式,再判断pass count是否满足,下例中,pass count中传入的是15,每15次命中断点才会触发断点,挂起程序

    Pass count

未完待续

​ 如果您对内容比较感兴趣且认可,希望您动动热情的小手关注收藏加转发哦,后续更精彩,接下来会讲到如下内容

  • 断点调试技巧
  • 远程调试与热更新技术
  • JVM TI与JDB、阿里巴巴开源工具Arthas实现原理
  • Java程序诊断技巧
  • 单元测试之junit、testng以及mock用法

image-20210304151723835

正文到此结束
Loading...