Как увеличить количество отображаемых строк дампа трассировки Java-стека?

Есть ли способ сделать Throwable.printStackTrace(PrintStream s) распечатать полную трассировку стека, чтобы я мог видеть за последней строкой "... 40 more"

Ответ 1

Вам не нужно; эта информация присутствует в другом месте в трассировке стека. Из документов printStackTrace():

Обратите внимание на наличие строк, содержащих символы "...". Эти строки указывают на то, что оставшаяся часть трассировки стека для этого исключения совпадает с указанным числом кадров из нижней части трассировки стека исключения, вызванного этим исключением (исключение "охватывающего" ).

Эта стенограмма может значительно уменьшить длину вывода в общем случае, когда обернутое исключение выбрано из того же метода, что и "причинное исключение".

Другими словами, "... x more" появляется только в цепочном исключении и только тогда, когда последние строки x трассировки стека уже присутствуют как часть другой цепочки отслеживаемых цепочек исключений.

Предположим, что метод ловит исключение Foo, завершает его в панели исключений и бросает Bar. Затем трассировка стека Foo будет сокращена. Если вам по какой-то причине требуется полная трассировка, все, что вам нужно сделать, это взять последнюю строку перед ... в трассировке стека Foo и искать ее в трассе стека Bar; все ниже этой строки - это то, что было бы напечатано в трассировке стека Foo.

Ответ 2

Быстро догадайтесь о методе для вас.

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

Ответ 3

Давайте возьмем трассировку стека из документации 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

Причины отображаются от самой вложенной внизу ("первопричина") до той, к которой принадлежит отпечаток стека.

В этом случае основной причиной является LowLevelException, который вызвал MidLevelException, который вызвал HighLevelException.

Чтобы получить полную трассировку стека, вы должны взглянуть на кадры включающего исключения (и включающих его исключений):

  1. Посмотрите, сколько кадров было опущено: "... X больше"
  2. Ищите пропущенные кадры во включающем исключении
    1. Посмотрите, как много кадров были опущены: "... Y больше"
    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)

Примечания стороны:

  • Могут быть случаи, когда кадры не указаны, например:

    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