Stackwalker 的帧少于 stacktrace 的元素

Stackwalker has less frames than stacktrace has elements

我对 Java 9 的 Stackwalking API 进行了一些试验,发现收集到的帧少于实际堆栈跟踪给出的帧。我想知道是否有可能获得相同数量的框架和元素?

看看下面的测试:

@Test
public void test() {
    NaughtyBusiness nb = new NaughtyBusiness();
    try {
        //This method throws an exception
        nb.callMeForGoodTime(NaughtyBusiness.AlcoholTolerance.LOW);
    } catch (Exception e) {
        StackTraceElement[] stackTrace = e.getStackTrace();

        StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.SHOW_HIDDEN_FRAMES);
        List<StackWalker.StackFrame> frames = 
                            stackWalker.walk(stackFrameStream -> stackFrameStream.collect(toList()));
       
        System.out.println(frames);
    }
}

现在,如果我调试代码,我会看到以下内容:

第一个明显的区别是 StacktraceElements 与 StackFrames 的数量(26 对 23)。更令人惊讶的是,丢失的帧(标记为红色)是真正有趣的帧,即来自我的自定义代码,而两者共享的绿色部分只是样板文件。

因此问题是,我如何使用 StackWalking API 获取“丢失”的帧?我已经尝试了 SHOW_HIDDEN_FRAMESRETAIN_CLASS_REFERENCESHOW_REFLECT_FRAMES 这 3 个选项,但 none 有效。

StackWalker.walk 方法从调用它的地方构建堆栈帧。在本例中,您从 test() 方法调用它,因此它构建了一系列以该方法开头的堆栈帧。

StackWalker 根本不知道你捕获的异常。异常是从不同的地方抛出的,即 NaughtyBusiness.playStupidGamesWinStupidPrizes 方法,这就是它的堆栈帧不同的原因。

要获取与异常堆栈帧相同的 StackWalker 帧,您需要从引发异常的同一方法调用 StackWalker.walk