NullPointerException异常堆栈跟踪不可用而不调试代理
-
21-08-2019 - |
题
我最近发现,导致一个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子句,但在抓,我打印的值:
e.getStackTrace().length
如果没有这个调试器打印“0”,与调试器它打印(在这种情况下9)的正数。
更多信息:这是发生在JDK 1.6.0_13,64位,AMD64,LINUX 2.6.9
解决方案
是否有可能这个代码是在内环?然后再JIT编译器可能会被编译调用堆栈这为本地代码,失去了堆栈信息。然后,当你连接调试程序,它禁用了JIT,从而再次可用的信息。
在其它手动例外持续显示信息作为JIT不优化。
它看起来像这样有时会在管路102发生用于他人在这个类的源代码的注释:
HTTP://logging.apache。组织/ log4j的/ 1.2 /外部参照/组织/阿帕奇/ log4j的/ SPI / LocationInfo.html
其他提示
随着JVM标志-XX:-OmitStackTraceInFastThrow您可以禁用JVM的性能优化这个用例。如果该参数被给出,其中将禁用标志,则栈跟踪可用。
有关的更多信息,请看看下面的发行说明:
冷‘内置的例外。由于性能的目的,当这样的抛出异常几次,该方法可以被重新编译。重新编译之后,编译器“,在服务器VM现在提供正确栈回溯所有编译器’ 。可以使用预分配的例外,不提供堆栈跟踪选择更快的战术完全禁止使用预分配异常,使用这个新的标志:-XX:-OmitStackTraceInFastThrow” http://java.sun.com/j2se/1.5.0/relnotes.html
我可以复制这一点,但它似乎有点奇怪,这将在您的行动某处发生。
如果调用setStackTrace一个空数组,即会导致要仅显示文本。
public class Fark {
public static void main(String[] args) {
try {
Fark.throwMe(args.length != 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static final void throwMe(boolean arg) throws Exception{
Exception e = new NullPointerException();
if (arg) {
e.setStackTrace(new StackTraceElement[0]);
}
throw e;
}
}
运行它....
% java Fark
java.lang.NullPointerException
at Fark.throwMe(Fark.java:15)
at Fark.main(Fark.java:5)
% java Fark nothing
java.lang.NullPointerException