我最近发现一个导致NullPointerException的bug。异常通过一个标准的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、64位、amd64、linux 2.6.9上发生的。