Вопрос по java – Получить текущую трассировку стека в Java

913

Как получить текущую трассировку стека в Java, например, как в.СЕТЬ ты можешь сделатьEnvironment.StackTrace?

КСТАТИ,Thread.dumpStack() это не то, что я хочу - я хочу получитьтрассировки стека обратно, а не распечатывать.

Я всегда использую & quot; новое Exception (). PrintStackTrace () & quot; в качестве часового выражения, когда я отлаживаю в Eclipse. Это удобно, когда вы останавливаетесь в точке останова и хотите знать, откуда вы пришли. Tim Büthe
@ TimB & # xFC; the: не является ли Eclipse уже сообщающим вам трассировку стека, когда вы находитесь в режиме отладки? Я думаю так. Luigi Massa Gallerano
Arrays.toString (Thread.currentThread () getStackTrace ().); достаточно просто. Ajay
@Arkanon Это относится к Java, и показывает, как они будут делать это в .net и каков эквивалент в Java. Pokechu22
Чтобы хорошо его распечатать, вы можете использовать apache StringUtils: StringUtils.join (currentThread (). GetStackTrace (), & quot; \ n & quot;); Art

Ваш Ответ

22   ответа
23

import android.util.Log;
String stackTrace = Log.getStackTraceString(exception); 
android.util.Log.getStackTraceStringdeveloper.android.com/reference/android/util/Log.html
Где определяется getStackTraceString? Это из сторонней библиотеки логов?
171
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
    System.out.println(ste);
}
Мне это нравится больше всего, потому что у вас есть возможность избавиться от шума, завернув свое заявление println, например,for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
В Java есть метод printStackTrace, определенный в Throwable, вы можете сделать:new Exception().printStackTrace(System.out) что я помню, цикл for, вероятно, имеет меньше накладных расходов, но вы все равно должны использовать это только как средство отладки ...
14

Thread.currentThread().getStackTrace();

-2

System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));

Это поможет вам распечатать трассировку стека без цикла.

Error: User Rate Limit Exceeded
20

35 31 символов):

new Exception().printStackTrace();   
new Error().printStackTrace();
отличное решение. Теперь мне не нужно перебирать все кадры стека
11

Я предполагаю, что

  Thread.dumpStack()

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

Ладно, на самом деле dumpStack () является статическим методом, и к нему следует обращаться статическим способом. Спасибо, затмение!
Я люблю ярлык, но исходный код этого метода:new Exception("Stack trace").printStackTrace(); так что это на самом деле строит Throwable
-1

Thread.currentThread().dumpStack();

Больше информации и методов там: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html

Error: User Rate Limit ExceededThread.dumpStack()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
4

catch(Exception e)
{
    StringWriter writer = new StringWriter();
    PrintWriter pw = new PrintWriter(writer);
    e.printStackTrace(pw);
    String errorDetail = writer.toString();
}

Строка «errorDetail» содержит трассировку стека

7

который возвращает строку с трассировкой стека:

static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw, true);
    t.printStackTrace(pw);
    pw.flush();
    sw.flush();
    return sw.toString();
}

И просто логит как ...

... 
catch (FileNotFoundException e) {
    logger.config(getStackTrace(e));
}
Является ли регистратор встроенным регистратором или созданным вами и записанным в файл.
@Doug Hauf, logger - это ссылка на встроенный Java Logger. Убедитесь, что вы настроили файл logging.properties. Добавьте его в начало вашего класса следующим образом: private static final Logger logger = Logger.getLogger (Your_Class_Name.class.getName ());
Это похоже на один авто, сгенерированный Netbeans.
Он существовал и в 2012 году. Дата, к сожалению, не имеет значения в вашем случае. См. [Ссылка] (docs.oracle.com/javase/1.5.0/docs/api/java/util/logging/Logger.html#log (java.util.logging.Level, java.lang.String, java.lang .Throwable)), [ссылка] (docs.oracle.com/javase/1.5.0/docs/api/java/util/logging/Logger.html#log (java.util.logging.LogRecord)) и т. Д. несколько функций, которые передаютThrowable прочьHandlerдоFormatterв 2012 году, который был Java7, больше, чем я перечислил здесь. И эти функции работают намного дольше, чем Java7; отсюда J2SE 5.0 javadocs)
java.util.logging.Logger#log(Level, String, Throwable) уже делает это. Это переписывает вещи, которые уже существуют в стандартной библиотеке Java без необходимости, и указывает новым разработчикам в неправильном направлении, что далеко от документации. Делая это сейчас, вы заставили Stacktrace отформатировать определенным образом, где в качествеlogging API позволяет динамически изменять форматирование оператора журнала по мере его указания. Насколько мне известно,log4j также имеет аналогичное поведение. Не изобретайте велосипед, потому что вы теряете вещи, как я объяснил.
1071

Нить.currentThread (). getStackTrace ().

Это возвращает массивStackTraceElements, которые представляют текущий след стека программы.

Одна строка для преобразования трассировки стека в строку, которая работает, когда у вас нет исключения, и вы не используете Apache Arrays.toString (Thread.currentThread (). GetStackTrace ())
Как указано во многих ответах ниже -new Throwable().getStackTrace() намного быстрее, потому что не нужно проверятьthis != Thread.currentThread() и обходит потенциальные издержки JVM при вызове через дочерний класс (Exception extends Throwable)
Первый элемент (индекс 0) в массиве - это метод java.lang.Thread.getStackTrace, второй (индекс 1) обычно представляет первый интерес.
Крутая однострочная строка, если вы уже используете Apache Commons для получения строки:String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e); stackoverflow.com/a/10620951/11236 ripper234
Решение @Tony лучше, потому что оно не требует броска
2

если хотите проверить текущий стек вызовов вашего процесса.

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [[email protected]]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message
9

Струна с гуавой:

Throwables.getStackTraceAsString(new Throwable())
2

public final class DebugUtil {

    private static final String SEPARATOR = "\n";

    private DebugUtil() {
    }

    public static String formatStackTrace(StackTraceElement[] stackTrace) {
        StringBuilder buffer = new StringBuilder();
        for (StackTraceElement element : stackTrace) {
            buffer.append(element).append(SEPARATOR);
        }
        return buffer.toString();
    }

    public static String formatCurrentStacktrace() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        return formatStackTrace(stackTrace);
    }
}
246
Thread.currentThread().getStackTrace();

new Throwable().getStackTrace();

будет иметь определенную позицию для вашего текущего метода, если это имеет значение.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded(new Exception()).getStackTrace()Error: User Rate Limit ExceededThread.currentThread().getStackTrace();
Error: User Rate Limit Exceeded
(new Throwable()).getStackTrace()Error: User Rate Limit Exceededbugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 )
59
Thread.currentThread().getStackTrace();

Для более старой версии вы можете перенаправитьexception.printStackTrace() кStringWriter() :

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace() доступно с JDK1.4 & # x2026;
9

public static void showTrace() {

  List<StackFrame> frames =
    StackWalker.getInstance( Option.RETAIN_CLASS_REFERENCE )
               .walk( stream  -> stream.collect( Collectors.toList() ) );

  for ( StackFrame stackFrame : frames )
    System.out.println( stackFrame );
}
14

как комментарий к принятому ответу, дал то, что кажется лучшим ответом, который на самом деле отвечаетthe OP's question:

Arrays.toString(Thread.currentThread().getStackTrace());

... ОП сделалNOT спросите, как получитьString от трассировки стека отException, И хотя я большой поклонник Apache Commons, когда есть что-то столь же простое, как и выше, нет логической причины использовать стороннюю библиотеку.

У меня есть список потоков, и мне нужно распечатать их следы стека.
В этом случае убедитесь, что вы используетеThread.getAllStackTraces() который дает вамMap<Thread, StackTraceElement[]>, Hotspot будет защищать все потоки всякий раз, когда это необходимо. Zing может привести отдельные темы в безопасную точку, не мешая другим. Получение трассировки стека требует безопасной точки.Thread.getAllStackTraces() получает все трассировки стека и останавливает все потоки только один раз. Конечно, вы должны выяснить, какое отображение вам на самом деле интересно.
19

вы можете использовать утилиту jstack, JConsole или отправить сигнал kill -quit (в операционной системе Posix).

Однако, если вы хотите сделать это программно, вы можете попробовать использовать ThreadMXBean:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);

for (ThreadInfo info : infos) {
  StackTraceElement[] elems = info.getStackTrace();
  // Print out elements, etc.
}

Как уже упоминалось, если вам нужна только трассировка стека текущего потока, это намного проще - просто используйтеThread.currentThread().getStackTrace();

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededSystem.err.println(elems[i]) на каждой). Вторая строка во фрагменте отсутствуетbean.Error: User Rate Limit ExceededdumpAllThreads но я думаю, что большинство людей могли бы решить это.
4
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

which is the least recent method invocation in the sequence.

A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().

переберите StackTraceElement и получите желаемый результат.

for (StackTraceElement ste : stackTraceElements ) 
{
    //do your stuff here...
}
также .toString () будет красиво выводить все эти данные в строку
Спасибо за упоминание, что последний элемент содержит самый последний. Против интуитивно понятно и сэкономило мне время.
6
try {
}
catch(Exception e) {
    StackTraceElement[] traceElements = e.getStackTrace();
    //...
}

или же

Thread.currentThread().getStackTrace()
действительно, это будет
Разве ваш лучший пример даст вам только трассировку стека относительно блока try / catch?
в чем различия между двумя
38

String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
Это хорошее решение в одну строку. К вашему сведению, для тех, кто используетorg.apache.commons.lang3, полная строка:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
Это очень полезно! При отладке с использованием IDE (например, IntelliJ IDEA), лучше использоватьExceptionUtils.getStackTrace(new Throwable()) выражение для получения трассировки стека.
Просто для повторения комментария смещения файла при переходе кorg.apache.commons.lang3, который я изначально упустил из виду - импорт используетlang3 вместоlangи заменяетgetFullStackTrace сgetStackTrace.
4

Getting stacktrace:

Printing stacktrace (JAVA 9+):

Arrays.asList(ste).stream().forEach(System.out::println);

Printing stacktrage (JAVA 7):

StringBuilder sb = new StringBuilder();

for (StackTraceElement st : ste) {
    sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);

Похожие вопросы