java - NullPointerException 堆栈跟踪在没有调试代理的情况下不可用

标签 java logging stack-trace nullpointerexception

我最近发现了一个导致 NullPointerException 的错误。使用标准 slf4j 语句捕获并记录异常。代码如下:

for(Action action : actions.getActions()) {
    try {
        context = action.execute(context);
    } catch (Exception e) {
        logger.error("...", e);
        break;
    }
}

如您所见,没什么特别的。但是,在我们拥有的所有异常日志语句中,只有这一条不会打印堆栈跟踪。它只打印消息(表示为“...”)和异常类的名称(java.lang.NullPointerException)。

由于异常的堆栈跟踪是延迟加载的,我认为可能存在某种指令重新排序问题,并决定在日志语句之前调用 e.getStackTrace()。这没什么区别。

所以我决定在启用调试代理的情况下重新启动。但是,因为我什至附加到进程,我注意到现在堆栈跟踪正在打印。很明显,调试代理的存在导致一些额外的调试信息可用。

从那时起,我已经修复了异常的根本原因。但是我想了解为什么没有调试器就无法使用堆栈跟踪。有人知道吗?

澄清:这不是日志记录问题。想象一下同样的 try/catch 子句,但是在 catch 中,我打印了以下值:

e.getStackTrace().length

如果没有调试器,它会打印“0”,如果有调试器,它会打印一个正数(在本例中为 9)。

更多信息:这发生在 JDK 1.6.0_13、64bit、amd64、linux 2.6.9 上

最佳答案

使用 JVM 标志 -XX:-OmitStackTraceInFastThrow,您可以针对此用例禁用 JVM 的性能优化。如果给出了这个参数,它会禁用标志,堆栈跟踪将可用。

有关更多信息,请查看以下发行说明:

“服务器VM中的编译器现在为所有“冷”内置异常提供正确的堆栈回溯。出于性能目的,当此类异常被抛出几次时,该方法可能会重新编译。重新编译后,编译器可以使用不提供堆栈跟踪的预分配异常选择更快的策略。要完全禁用预分配异常,请使用这个新标志:-XX:-OmitStackTraceInFastThrow。 http://java.sun.com/j2se/1.5.0/relnotes.html

关于java - NullPointerException 堆栈跟踪在没有调试代理的情况下不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1076191/

相关文章:

objective-c - 使用 atos 通过 dSYM 确定崩溃的方法名称

java - Gson 和通过继承序列化对象的 ArrayList

Java并行处理数组

batch-file - MOVE 操作后批量创建失败日志文件

python - 使用 nginx、uwsgi、flask 轻松进行应用程序日志记录/调试?

java - 奇怪的崩溃。很少的代码,了解堆栈跟踪

java - 如何覆盖 JPanel 的默认布局管理器?

java - 在 Java lambda 中使用两个流来计算协方差

mysql - 我应该使用 mysql 来保存日志,还是只转储到文本文件

javascript - 包装 `console.log` 并保留调用堆栈