`

Bug分析之异常变量堆栈信息

阅读更多

 

 

 

异常是一种特殊的类,在创建异常时保存创建时的方法调用堆栈镜像。即,为了保留异常出现时的实时堆栈信息,不应复用异常,每个异常均需单独new方式生成。

 

下面演示一段有问题的代码并进行分析

 

1.问题代码

 

a)自定义异常定义

package demo.bce;
 
public class MyException extends RuntimeException {
 
    private static final long serialVersionUID = -3802919537257556719L;
 
    private String id;
 
    public MyException(String id) {
       super();
       this.id = id;
    }
 
    public String getId() {
       return id;
    }
 
    public void setId(String id) {
       this.id = id;
    }
 
    @SuppressWarnings("unused")
    private MyException() {
    }
 
}

 


 

b)自定义异常常量

 

package demo.bce;
 
public final class MyExceptionContext {
 
    // x1,x2,y1,y2的Throw相关堆栈信息在创建时一次性生成(不再变化)
    // 即使用此异常会得到错误的堆栈描述信息
    public static final MyException x1 = new MyException("X1");
    public static final MyException x2 = new MyException("X2");
 
}

  


 

c)测试代码

 package demo.bce;

 
 
public class MyMain {
 
    public static void main(String[] args) {
       testx();
    }
 
    // ///
 
    private static void testx() {
       try {
           x11();
       } catch (Exception e) {
           e.printStackTrace();
       }
       try {
           x12();
       } catch (Exception e) {
           e.printStackTrace();
       }
       try {
           x21();
       } catch (Exception e) {
           e.printStackTrace();
       }
       try {
           x22();
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
 
    private static void x11() {
       throw MyExceptionContext.x1;
    }
 
    private static void x12() {
       throw MyExceptionContext.x2;
    }
 
    private static void x21() {
       throw MyExceptionContext.x1;
    }
 
    private static void x22() {
       throw MyExceptionContext.x2;
    }
 
}
 


 

d)测试结果

 

demo.bce.MyException

    at demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7)

    at demo.bce.MyMain.x11(MyMain.java:36)

    at demo.bce.MyMain.testx(MyMain.java:14)

    at demo.bce.MyMain.main(MyMain.java:7)

demo.bce.MyException

    at demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8)

    at demo.bce.MyMain.x11(MyMain.java:36)

    at demo.bce.MyMain.testx(MyMain.java:14)

    at demo.bce.MyMain.main(MyMain.java:7)

demo.bce.MyException

    at demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7)

    at demo.bce.MyMain.x11(MyMain.java:36)

    at demo.bce.MyMain.testx(MyMain.java:14)

    at demo.bce.MyMain.main(MyMain.java:7)

demo.bce.MyException

    at demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8)

    at demo.bce.MyMain.x11(MyMain.java:36)

    at demo.bce.MyMain.testx(MyMain.java:14)

    at demo.bce.MyMain.main(MyMain.java:7)

 

 

代码实际上在四个不同的方法中抛出了两个不同的异常,但抛到四个异常的堆栈信息居然完全一致。

 

另外,x11x21虽然抛同一个异常,但x11的异常无stackTracex21的异常有stackTrace信息。

 

2.代码分析和猜想

 

MyExceptionContext首次被调用时才生成常量异常x1x2。注意x1x2是同时生成的,且基本上处于相同的方法调用环境。故x1x2的方法调用堆栈信息基本一致,进而在实际使用时严重误导异常的抛出分析。

 

另外,通常情况下,异常是需要设置cause的。因此,也不应该尝试常量异常(cause每次可能不一样)。

 

3.简单总结

 

使用异常时实时new一个出来返回以获取正确方法调用堆栈信息。

  

 

 

 

分享到:
评论

相关推荐

    PHP中获取变量的变量名的一段代码的bug分析

    复制代码 代码如下: /** * 获取变量名 * * @param $string * @... //在函数中不要直拉遍历$GLOBALS,会出现堆栈问题 foreach($allvar as $k=&gt;$v){ //变量值相同,可能不是相同变量,因多个变量的值可能相同 if ($src

    Delphi实例源码演示栈分配中的暗藏BUG

    摘要:Delphi源码,系统相关,动态数组,静态数组  示Delphi例用于演示栈分配中一... 静态数组的局部变量总会在栈上分配,因此如果堆栈大小不够,将会导致异常。  本例中调用StackOver()总会发生异常:Stack overflow。

    bug-tracker:使用MERN堆栈构建的Bug跟踪器Web应用程序,并使用JWT添加了身份验证

    使用MERN堆栈构建的Bug跟踪器Web应用程序,并使用JWT添加了身份验证 开始吧 首先,在/ api下使用变量SECRET_KEY和URI创建一个.env文件: SECRET_KEY:用于JWT签名的密钥 URI:Mongo数据库的URI 端口:API端口 接...

    阿里巴巴编码规范 基础技能认证 考题分析(考题+答案).docx

    异常信息应该包括两类信息:案发现场信息和异常堆栈信息。 B .日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。 C .避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=...

    【新】易语言异常捕获,基于东灿大佬的异常捕获模块5-2版本-易语言

    本程序基于东灿的异常调试模块5.2部分版权信息如下: 1. 该模块功能是补足易错误管理器无法捕捉的异常。 2. 本模块可以截获许多异常,比如内存读写错误,非法汇编指令,算术异常,其他异常等等。 3. 本模块拥有try/...

    pinvoke-stack-bug:由输出参数中的结构打包导致的PInvoke错误的演示代码,将覆盖不相关的堆栈变量

    我的演示代码,建议您在尝试该代码时阅读。

    bug-tracker:Bug跟踪应用程序,具有团队合作支持。 用w PERN堆栈+ TypeScript制作

    错误跟踪器| PERN-TypeScript 使用PERN + TS制作的错误跟踪应用 ...Dotenv-从.env文件加载环境变量 特征 身份验证(使用用户名和密码登录/注册) CRUD项目,可以添加成员以进行小组工作 具有标题,描述和优先

    第8节-实用调试技巧.pdf

    这些信息包括临时变量的值、内存信息、调用堆栈、汇编信息、寄存器信息等。 七、多多动手,尝试调试 调试需要大量的实践和经验。初学者可能需要花费80%的时间在写代码,20%的时间在调试。但是一个程序员可能需要...

    集编辑调试运行一体的开源、跨平台、轻便的国产多功能Python IDE

    NovalIDE 1.1.7 隆重发布,新版本添加了以下重磅功能!...可查看调式堆栈信息 允许调式添加断点和监视变量 支持了一些文本格式化操作 修复了已知的一些BUG 软件官方网址:http://www.novalide.com

    small_rtos1.20.3

    更正for keil c51 移植的堆栈在某种情况下初始值错误。 0.51版 2002年3月10日 修改函数OSWait使其占用资源更少,兼容性更好。 更正for keil c51 移植的C_OSCtxSw函数的错误。 0.50版 2002年2月22日

    用vs2010调试asp

    * 最下面的一些提示栏还是很有帮助的,比如调用堆栈,局部变量,监视等。 四、调试工具栏 调试工具栏中有很多按钮,下面是常用的几个: * 点击绿色三角则让程序继续执行,如果后面有断点或者stop则又会中断,否则...

    传智播客扫地僧视频讲义源码

    本教程共分为5个部分,第一部分是C语言...11_异常类型_异常变量的生命周期下_传智扫地僧 12_中午知识点梳理 13_异常的层次结构_传智扫地僧 14_标准异常库 15_流类库结构 16_标准IO_输入api_上 17_标准IO_输入api_下 ...

    [java]读书笔记整理:一切都是对象

    变量生命周期的混乱往往会导致大量的程序Bug,接下来将介绍java是怎样替我们完成所有的清理工作,从而大大地简化这个问题的。 作用域 大多数过程型语言都有作用域(Scope)的概念。作用域决定了在其内定义的变量...

    C#探秘系列(三)——StackTrace,Trim

     可能我们看到最多的就是catch中的e参数,里面会有一个StackTrace,然后不可否认的这玩意太有用了,它会把调用堆栈中的信息输出出来,有了它,我们就可以快速的知道运行代码的执行流并且快速的定位到问题。...

    Linux高级bash编程

    文件信息:对包含在变量中的文件列表进行操作 10-4. 在for循环中操作文件 10-5. 在for循环中省略[list] 10-6. 使用命令替换来产生for循环的[list] 10-7. 对于二进制文件的一个grep替换 10-8. 列出系统上的所有用户 ...

    Advanced Bash-Scripting Guide <>

    文件信息:对包含在变量中的文件列表进行操作 10-4. 在for 循环中操作文件 10-5. 在for 循环中省略[list] 10-6. 使用命令替换来产生for 循环的[list] 10-7. 对于二进制文件的一个grep 替换 10-8. 列出系统上的所有...

    精易模块[源码] V5.15

    3、修正“类_环境存取-&gt;读环境变量”不能读取当前进程环境变量的BUG,感谢易友【@詠不言敗】反馈。 4、修正“文本_逐字分割”返回数组不清除会保留上次内容的问题,感谢易友【@JadeジYu】反馈。 5、新增“文本_是否...

    基于C++中常见内存错误的总结

    在系统开发过程中出现的bug相对而言是比较好解决的,花费在这个上面的调试代价不是很大,但是在系统集成后的bug往往是难以定位的bug(最好方式是打桩,通过打桩可以初步锁定出错的位置,如:进入函数前打印日志,...

    STM32调试过程中遇到的问题12题.doc

    解决方法:将该工程的主要的 main.c 文件,lcd.c 文件,lcd.h 头文件等,复制到另一个正常运行的标准库工程里面,修改 bug 后,运行,好了。 问题 10:某教程的 stm32F1 的串口配置文件结构比较好,但确少:NVIC_...

    Android虚拟机调试器原理与实现

    本文主要讲解Android虚拟机动态调试背后涉及到的技术原理,除了JDWP协议细节,还包括任意位置断点、堆栈输出、变量值获取等基础调试功能的具体实现。另外本文提供了一款新的android动态调试工具——AVMDBG,提供调试...

Global site tag (gtag.js) - Google Analytics