Stackwalker 的帧数少于 stacktrace 的元素数

Cof*_*Pro 2 java stack-trace java-9

我正在尝试使用 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

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

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

VGR*_*VGR 5

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

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

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