如何增加Java堆栈跟踪转储的显示行数?

and*_*bd1 91 java exception

有没有办法Throwable.printStackTrace(PrintStream s)打印完整的堆栈跟踪,以便我可以看到超出最后一行"... 40 more"

Mic*_*ers 115

你不需要; 该信息存在于堆栈跟踪的其他位置.来自以下文件printStackTrace():

请注意包含字符的行的存在"...".这些行表示此异常的堆栈跟踪的剩余部分匹配由此异常("封闭"异常)引起的异常的堆栈跟踪底部的指示帧数.

这种简写可以大大减少输出的长度,在这种情况下,从捕获"致使异常"的同一方法抛出包装异常.

换句话说,"... x more"仅出现在链式异常中,并且仅当x堆栈跟踪的最后几行已作为另一个链式异常的堆栈跟踪的一部分出现时.

假设一个方法捕获异常Foo,将其包装在异常Bar中,并抛出Bar.然后Foo的堆栈跟踪将缩短.如果由于某种原因需要完整的跟踪,那么您需要做的就是...在Foo的堆栈跟踪之前取最后一行并在Bar的堆栈跟踪中查找它; 该行下面的所有内容都与Foo的堆栈跟踪中的内容完全相同.


Mar*_*234 12

让我们从Throwable.printStackTrace()的文档中获取堆栈跟踪:

HighLevelException: MidLevelException: LowLevelException
    at Junk.a(Junk.java:13)
    at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
    at Junk.c(Junk.java:23)
    at Junk.b(Junk.java:17)
    at Junk.a(Junk.java:11)
    ... 1 more
Caused by: LowLevelException
    at Junk.e(Junk.java:30)
    at Junk.d(Junk.java:27)
    at Junk.c(Junk.java:21)
    ... 3 more
Run Code Online (Sandbox Code Playgroud)

原因从底部最嵌套的原因(“根本原因”)到打印的堆栈跟踪所属的原因显示。

在这种情况下,根本原因是LowLevelException,哪个导致的MidLevelException,哪个导致的HighLevelException

要获得完整的堆栈跟踪,您必须查看封闭异常(及其封闭异常)的帧:

  1. 看看省略了多少帧:“... X more”
  2. 在封闭的异常中查找省略的帧
    1. 看看省略了多少帧:“... Y more”
    2. 将第一个 X - Y 帧附加到堆栈跟踪
  3. 如果 Y > 0,则重复步骤 2,并将其作为省略的帧数

因此,如果我们想获得完整的堆栈跟踪,LowLevelException我们将执行以下操作:

  1. 看看省略了多少帧:“……还有3帧”
  2. 在封闭的异常处查找省略的帧 ( MidLevelException)
    1. 已省略 1 帧(“... 1 个以上”)
    2. 将前 2 (3 - 1) 帧附加到堆栈跟踪
  3. 重复步骤 2,将 1 作为省略帧的数量
    1. 查看MidLevelException( HighLevelException)的封闭异常
    2. 将前 1 帧附加到堆栈跟踪

完整的堆栈跟踪如下所示:

LowLevelException
    at Junk.e(Junk.java:30)
    at Junk.d(Junk.java:27)
    at Junk.c(Junk.java:21)
    // From MidLevelException stack trace
    at Junk.b(Junk.java:17)
    at Junk.a(Junk.java:11)
    // From HighLevelException stack trace
    at Junk.main(Junk.java:4)
Run Code Online (Sandbox Code Playgroud)

旁注:

  • 可能存在没有列出框架的情况,例如:

    HighLevelException: MidLevelException
        at Junk.main(Junk.java:4)
    Caused by: MidLevelException
        ... 1 more
    
    Run Code Online (Sandbox Code Playgroud)

    当它在同一行中创建的原因时,可能会发生这种情况:new HighLevelException(new MidLevelException())。不要对此感到困惑,上述方法仍然有效,只是异常中没有可使用的框架,请继续使用其封闭的框架。

  • 在某些情况下,您可以通过查看未省略的第一帧(上面的行... X more)来节省计数。如果您知道哪些方法调用该行中的方法,您可以直接在封闭异常的框架中搜索调用者:

    HighLevelException: MidLevelException: LowLevelException
        at Junk.c(Junk.java:29)
        at Junk.b(Junk.java:21)
        at Junk.a(Junk.java:13)
        at Junk.main(Junk.java:4)
    Caused by: MidLevelException
        // You know Junk.d is only called by Junk.b
        at Junk.d(Junk.java:35)
        ... 3 more
    
    Run Code Online (Sandbox Code Playgroud)


jjn*_*guy 5

快速猜测一种方法.

static void printLongerTrace(Throwable t){
    for(StackTraceElement e: t.getStackTrace())
        System.out.println(e);
}
Run Code Online (Sandbox Code Playgroud)