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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1167888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:27:50  来源:igfitidea点击:

How do I increase the number of displayed lines of a Java stack trace dump?

javaexception

提问by andersonbd1

Is there a way to make Throwable.printStackTrace(PrintStream s)print the full stack trace, so that I can see beyond the final line of "... 40 more"?

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

采纳答案by Michael Myers

You don't need to; that information is present elsewhere in the stack trace. From the docs of printStackTrace():

你不需要;该信息存在于堆栈跟踪中的其他地方。来自以下文档printStackTrace()

Note the presence of lines containing the characters "...". These lines indicate that the remainder of the stack trace for this exception matches the indicated number of frames from the bottom of the stack trace of the exception that was caused by this exception (the "enclosing" exception).

This shorthand can greatly reduce the length of the output in the common case where a wrapped exception is thrown from same method as the "causative exception" is caught.

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

在从与捕获“原因异常”相同的方法抛出包装异常的常见情况下,这种简写可以大大减少输出的长度。

In other words, the "... x more"only appears on a chained exception, and only when the last xlines of the stack trace are already present as part of another chained exception's stack trace.

换句话说,"... x more"只有当x堆栈跟踪的最后几行已经作为另一个链式异常堆栈跟踪的一部分出现时,才会出现在链式异常上。

Suppose that a method catches exception Foo, wraps it in exception Bar, and throws Bar. Then Foo's stack trace will be shortened. If you for some reason want the full trace, all you need to do is take the last line before the ...in Foo's stack trace and look for it in the Bar's stack trace; everything below that line is exactly what would have been printed in Foo's stack trace.

假设一个方法捕获了异常 Foo,将其包装在异常 Bar 中,然后抛出 Bar。然后 Foo 的堆栈跟踪将被缩短。如果您出于某种原因想要完整的跟踪,您需要做的就是在...in Foo 的堆栈跟踪之前的最后一行,并在 Bar 的堆栈跟踪中查找它;该行下方的所有内容都将在 Foo 的堆栈跟踪中打印出来。

回答by jjnguy

Quick guess at a method for you.

快速猜出适合您的方法。

static void printLongerTrace(Throwable t){
    for(StackTraceElement e: t.getStackTrace())
        System.out.println(e);
}

回答by Marcono1234

Let's take the stack trace from the documentation of Throwable.printStackTrace():

让我们从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

The causes are displayed from the most nested one at the bottom (the "root cause"), to the one which the printed stack trace belongs to.

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

In this case the root cause is LowLevelException, which caused MidLevelException, which caused HighLevelException.

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

To get the complete stack trace you have to look at the frames of the enclosing exception (and its enclosing exceptions):

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

  1. Look at how many frames were omitted: "... Xmore"
  2. Look for the omitted frames at the enclosing exception
    1. Look at how many frames were omitted: "... Ymore"
    2. Append the first X - Y frames to the stack trace
  3. If Y > 0, repeat step 2 with it as number of omitted frames
  1. 看看省略了多少帧:“... X更多”
  2. 在封闭异常处查找省略的帧
    1. 看看省略了多少帧:“... Ymore”
    2. 将第一个 X - Y 帧附加到堆栈跟踪
  3. 如果 Y > 0,则重复步骤 2,将其作为省略的帧数

So if we wanted to get the complete stack trace of LowLevelExceptionwe would do the following:

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

  1. Look at how many frames were omitted: "... 3more"
  2. Look for the omitted frames at the enclosing exception (MidLevelException)
    1. 1 frame has been omitted ("... 1more")
    2. Append the first 2 (3 - 1) frames to the stack trace
  3. Repeat step 2 with 1 as number of omitted frames
    1. Look at the enclosing exception of MidLevelException(HighLevelException)
    2. Append the first 1 frame to the stack trace
  1. 看看省略了多少帧:“……还有3个”
  2. 在封闭异常 ( MidLevelException) 处查找省略的帧
    1. 1 帧已被省略(“... 1more”)
    2. 将前 2 (3 - 1) 帧附加到堆栈跟踪
  3. 重复步骤 2,省略帧数为 1
    1. 查看MidLevelException( HighLevelException)的封闭异常
    2. 将第一个 1 帧附加到堆栈跟踪

Your complete stack trace then looks like this:

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

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)


Side notes:

旁注:

  • There might be cases where no frames are listed, e.g.:

    HighLevelException: MidLevelException
        at Junk.main(Junk.java:4)
    Caused by: MidLevelException
        ... 1 more
    

    This can happen when the cause it created in the same line: new HighLevelException(new MidLevelException()). Don't get confused by this, the approach described above still works, there are just no frames to use from the exception, continue with its enclosing one.

  • In some cases you can save yourself the counting by looking at the first frame which was not omitted (the line above ... X more). If you know which methods call the method in that line you can directly search for the callers in the frames of the enclosing exception:

    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
    
  • 可能存在未列出框架的情况,例如:

    HighLevelException: MidLevelException
        at Junk.main(Junk.java:4)
    Caused by: MidLevelException
        ... 1 more
    

    当它在同一行中创建的原因时可能会发生这种情况: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