Як збільшити кількість відображених рядків дампа трасування стека Java?


Відповіді:


122

Вам не потрібно; що інформація присутня в іншому місці трасування стека. З документів printStackTrace():

Зверніть увагу на наявність рядків, що містять символи "...". Ці рядки вказують на те, що залишок траси стека для цього винятку відповідає зазначеній кількості кадрів внизу траси стека винятку, який був викликаний цим винятком (виняток "що включає").

Цей скорочений запис може значно зменшити тривалість виводу в загальному випадку, коли загорнуте виняток викидається з того самого методу, що і "причинний виняток".

Іншими словами, "... x more"єдиний з'являється у ланцюговому винятку, і лише тоді, коли останні xрядки трасування стека вже присутні як частина трасування стека іншого ланцюгового виключення.

Припустимо, що метод ловить виняток Foo, обертає його в Bar винятку і кидає Bar. Тоді трасування стека Foo буде скорочено. Якщо ви з якихось причин хочете повну трасування, все, що вам потрібно зробити, це взяти останній рядок перед ...трасуванням стека у Foo і шукати його в трасі стека Bar; все нижче цього рядка - саме те, що було б надруковано у трасі стека Фу.


Останній абзац вводить в оману. Перекриття не буде, рядок раніше ...- це перший кадр, який відрізняється. Однак він буде принаймні в тому ж класі, який допомагає його знайти.
Marcono1234,

5

Швидко вгадайте спосіб для вас.

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

2

Візьмемо трасування стека з документації 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.