我最近发现,导致一个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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top