异常是一种特殊的类,在创建异常时会保存创建时的方法调用堆栈镜像。即,为了保留异常出现时的实时堆栈信息,不应复用异常,每个异常均需单独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)
代码实际上在四个不同的方法中抛出了两个不同的异常,但抛到四个异常的堆栈信息居然完全一致。
另外,x11和x21虽然抛同一个异常,但x11的异常无stackTrace,x21的异常有stackTrace信息。
2.代码分析和猜想
在MyExceptionContext首次被调用时才生成常量异常x1和x2。注意x1和x2是同时生成的,且基本上处于相同的方法调用环境。故x1和x2的方法调用堆栈信息基本一致,进而在实际使用时严重误导异常的抛出分析。
另外,通常情况下,异常是需要设置cause的。因此,也不应该尝试常量异常(cause每次可能不一样)。
3.简单总结
使用异常时实时new一个出来返回以获取正确方法调用堆栈信息。
分享到:
相关推荐
此时,开发人员可以通过异常堆栈回溯来分析导致异常的具体原因。堆栈回溯的过程是反向遍历堆栈帧,从当前执行点(也就是异常发生的地方)开始,逐级向上回溯到程序的入口点。 找出异常地址是异常堆栈回溯的核心任务...
在IT行业中,"BugReport dump txt"通常是指一种用于调试和问题排查的技术,它涉及到C++编程语言中的异常处理和堆栈跟踪。当程序运行时出现错误或异常,程序员会生成一个dump文件,该文件包含了程序崩溃时的内存状态...
BugReport是一份详细记录了应用程序在运行时出现问题的报告,包括错误日志、堆栈跟踪、系统状态等信息。它为开发者提供了诊断问题的关键线索,因为报告中通常会包含错误发生的时间、设备状态、应用版本以及用户操作...
它的分析范围广泛,包括空指针异常、未初始化的变量、资源泄漏等。通过在项目中集成FindBugs,开发者可以提前发现并修复这些问题,提高软件的稳定性和可靠性。 总之,Java查bug和查错是一项系统性工作,需要结合...
GoBug提供了源代码级别的调试支持,允许开发者设置断点,单步执行代码,查看变量值,调用堆栈信息等。这些功能对于理解代码执行流程和分析问题原因至关重要。通过断点,我们可以暂停程序在特定位置的执行,查看此时...
可以自定义日志类,将错误信息、堆栈跟踪等信息写入文件或发送到服务器,以便在软件崩溃后进行分析。 5. **崩溃后的快速定位**: 一旦软件崩溃,用户通常会看到一个“程序停止工作”的对话框。点击“查看详细信息...
在软件开发的过程中,Bug定位是一个关键的环节,它是保证软件质量的重要措施之一。随着人工智能技术的发展,其在Bug定位中的应用日渐成熟,能够大幅度提升定位Bug的效率与准确性。本次分享由饿了么的新零售新餐饮...
7. **故障排除流程**:在实际操作中,开发者首先会收到用户的".dmp"文件,然后使用调试工具分析异常原因,定位问题代码,修复后再进行测试验证,最后将修复更新推送给用户。 8. **持续集成/持续部署(CI/CD)**:在...
例如,在使用全局变量数组`$GLOBALS`时,作者提到避免直接遍历`$GLOBALS`,因为可能会导致堆栈问题。这实际上指向了一个更大的问题:PHP在处理递归函数时容易遇到的最大递归深度限制问题。当函数内部有对`$GLOBALS`...
5. **visible_windows.zip**:这可能包含有关用户界面(UI)状态的详细信息,比如活动的应用窗口、窗口堆栈等,对于分析UI问题或动画性能问题很有帮助。 6. **proto** 文件:这些通常是序列化数据,可能以协议缓冲...
- **分析错误报告**:通过错误信息、dump文件或调试工具来定位可能的出错位置。 - **检查代码**:查找可能导致溢出的函数,尤其是那些涉及大量局部变量或递归调用的函数。 - **边界检查**:在函数调用中添加边界...
3. **分析堆栈跟踪**:当程序抛出异常时,通常会附带一个堆栈跟踪(stack trace),显示了异常发生时的调用链路。仔细阅读堆栈跟踪可以帮助快速定位问题根源。 4. **单元测试**:编写针对关键功能的单元测试(unit ...
理解如何设置断点、单步执行、查看变量值和调用堆栈对于定位bug至关重要。 2. **异常处理**:C++的异常处理机制允许程序在遇到错误时抛出异常,而不是导致程序崩溃。通过`try-catch`块,开发者可以捕获并处理异常,...
通过理解和分析堆栈信息,开发者可以迅速定位问题所在,进而修复bug,提高应用的稳定性和性能。在实际工作中,结合日志记录、单元测试和持续集成等实践,可以更有效地管理和预防这类问题的发生。
- **调试器使用**:Visual Studio的调试器是强大的工具,可以设置断点,单步执行代码,检查变量值,查看调用堆栈,以及分析内存和线程状态。 - **监视窗口与快速监视**:通过监视窗口可以实时查看变量的变化,快速...
首先,qBreakpad是Qt平台上一个用于处理崩溃信息的开源库,它提供了捕获和分析崩溃堆栈的能力。qBreakpad的工作原理是在应用程序崩溃时捕获信息,生成一个.dmp文件,然后可以使用专用工具(如WinDbg、GDB等)对这个...
工具会自动匹配并显示崩溃的具体位置,以及相关的变量值和调用堆栈。相比于手动查找和解析,dSym分析工具大大提高了效率,减少了在调试过程中的时间和精力投入。 5. **应用场景** - **应用发布后的错误监控**:当...
这个文件通常只包含异常时相关的内存信息,而不包含所有共享内存(除非环境变量CORE_NOSHM未设置)。Core文件的格式依赖于操作系统,AIX系统中的格式可以参考/usr/include/sys/core.h或相关文档。 应用进程的Core ...
在计算机科学中,栈溢出是一种常见的编程错误,发生在程序的栈空间不足以存储所有的局部变量和函数调用信息时。如果栈溢出不被及时解决,可能会导致程序崩溃或出现未知的错误。因此,了解栈溢出的解决方法对于编程者...