Java에서 현재 스택 추적을 어떻게 얻을 수 있습니까?


1001

.NET에서와 같이 Java에서 현재 스택 추적 을 얻는 방법은 무엇 Environment.StackTrace입니까?

발견 Thread.dumpStack()했지만 원하는 것은 아닙니다. 스택 추적을 다시 인쇄하고 싶지는 않습니다.


73
Eclipse에서 디버깅 할 때 항상 "new Exception (). printStackTrace ()"를 시계 식으로 사용합니다. 중단 점에서 일시 중단하고 어디에서 왔는지 알고 싶을 때 편리합니다.
Tim Büthe

22
@ TimBüthe : 디버그 모드에있을 때 Eclipse가 이미 스택 추적을 알려주지 않습니까? 나도 그렇게 생각해.
Luigi Massa Gallerano

41
Arrays.toString (Thread.currentThread (). getStackTrace ()); 충분히 간단합니다.
Ajay

2
@Arkanon Java를 참조하며 .net에서 Java를 수행하는 방법과 Java에서 이에 해당하는 기능을 보여줍니다.
Pokechu22

9
잘 인쇄하려면 아파치 StringUtils를 사용할 수 있습니다. StringUtils.join (currentThread (). getStackTrace (), "\ n");
Art

답변:


1158

사용할 수 있습니다 Thread.currentThread().getStackTrace().

StackTraceElement프로그램의 현재 스택 추적을 나타내는의 배열을 반환합니다 .


48
: 이미 문자열 얻기 위해 아파치 평민을 사용하는 경우 멋진 한 줄 String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e); stackoverflow.com/a/10620951/11236
ripper234

5
배열의 첫 번째 요소 (인덱스 0)는 java.lang.Thread.getStackTrace 메소드이며, 두 번째 (인덱스 1)가 일반적으로 첫 번째 관심사입니다.
lilalinux

175
스택 추적을 예외가없고 Apache Arrays.toString (Thread.currentThread (). getStackTrace ())를 사용하지 않을 때 작동하는 문자열로 변환하는 하나의 라이너
Tony

9
@Tony의 솔루션은 던져 질 필요가 없기 때문에 더 좋습니다
mvd

3
아래의 많은 답변에서 지적했듯이 자식 클래스 ( )를 통해 호출하는 잠재적 JVM 오버 헤드 new Throwable().getStackTrace()를 확인 this != Thread.currentThread()하고 무시 할 필요가 없기 때문에 훨씬 빠릅니다.Exception extends Throwable
Vlad

264
Thread.currentThread().getStackTrace();

스택의 첫 번째 요소가 무엇인지 신경 쓰지 않으면 괜찮습니다.

new Throwable().getStackTrace();

중요한 경우 현재 방법에 대해 정의 된 위치를 갖습니다.


35
(new Throwable()).getStackTrace()실행 속도도 빠릅니다 ( bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 참조 )
MightyE

2
Thread.currentThread (). getStackTrace ()의 결과가 new Throwable (). getStackTrace ()와 어떻게 다른지 자세히 설명 할 수 있습니까? 둘 다 시도하고 Thread.currentThread (). getStackTrace ()는 인덱스 0에서 Thread.getStackTrace를 사용하여 배열을 반환하고 호출 방법은 인덱스 1에 있음을 발견했습니다. 새로운 Throwable (). getStackTrace () 메서드는 호출하는 배열을 반환합니다. 두 방법 모두 현재 방법에 대해 정의 된 위치를 가지고 있지만 위치는 다릅니다. 다른 차이점이 있습니까?
Ryan

9
@Ryan, Thread.currentThread (). getStackTrace ()가 다른 버전의 메소드에서 그 위치를 유지한다고 약속하지는 않습니다. 따라서 색인 1에 있는지 확인하면 Sun의 일부 버전의 JVM (1.5 또는 1.6, 기억하지 마십시오)에서는 색인 2입니다. 그것은 정의 된 위치가 의미하는 바입니다. 그곳에있을 것이며 앞으로도 계속 그곳에있을 것입니다.
Yishai

5
@MightyE 버그는 이제 Java 6에서 수정 된 것으로 닫힌 것으로보고되었습니다. 내부를 살펴보면 (new Exception()).getStackTrace()요청 된 스택 추적이 현재 스레드에있을 때 수행하는 것처럼 보입니다 (항상Thread.currentThread().getStackTrace();
M. Justin

3
@MJustin : 버그가 수정 된 것으로“현재”보고되지 않았으며, MightyE가 주석을 작성하기 6 년 전에 수정되었습니다. 실제로, 그것은 Stackoverflow가 설립되기 전에 수정되었습니다…
Holger

181
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
    System.out.println(ste);
}

20
java는 Throwable에 정의 된 printStackTrace 메소드를 가지고 new Exception().printStackTrace(System.out)있습니다. 기억할 수 있습니다. for 루프는 아마도 오버 헤드가 적을 수도 있지만 어쨌든 이것을 디버깅으로 사용해야합니다 ...
Jaap

2
나는 println 문장을 감싸서 노이즈를 제거 할 수있는 기회를 가지기 때문에이 방법이 가장 좋습니다.for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
nby

61
Thread.currentThread().getStackTrace();

JDK1.5부터 사용 가능합니다.

이전 버전의 경우, 리디렉션 할 수 있습니다 exception.printStackTrace()A를 StringWriter():

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();

3
new Throwable().getStackTrace()JDK1.4 이후부터 가능합니다…
Holger

40

이를 위해 Apache 공통점을 사용할 수 있습니다.

String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);

13
이것은 좋은 한 줄 솔루션입니다. 참고 org.apache.commons.lang3org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
로을

2
다만 투자 의견의 fileoffset의 의견에로 이동할 때 org.apache.commons.lang3가져 오기 사용 - 내가 처음에 간과하는 lang3대신 lang, 대체합니다 getFullStackTracegetStackTrace.
ggkmath

매우 유용합니다! IDE (예 : IntelliJ IDEA)를 사용하여 디버깅 할 때는 ExceptionUtils.getStackTrace(new Throwable())스택 추적을 얻기 위해 표현식을 사용하는 것이 좋습니다 .
Sergey Brunov


22

모든 스레드의 스택 추적을 얻으려면 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().


2
이 답변의 코드 스 니펫은 JVM에 QUIT 신호 (유닉스와 같은 시스템) 또는 Windows의 <ctrl> <break>를 보낼 때 표시되는 덤프 종류를 프로그래밍 방식으로 생성하는 데 가장 가깝습니다. 다른 답변과 달리 모니터 및 동기화 프로그램뿐만 아니라 스택 추적 만 볼 수 있습니다 (예 : StackTraceElement 배열을 반복하고 System.err.println(elems[i])각각 수행 하는 경우). 스 니펫의 두 번째 줄은 bean.전에 누락 dumpAllThreads되었지만 대부분의 사람들이 해결할 수 있다고 생각합니다.
George Hawkins

22

다른 솔루션 ( 35 31 자만 해당) :

new Exception().printStackTrace();   
new Error().printStackTrace();

1
멋진 솔루션. 지금은 모든 스택 프레임을 통해 루프가없는
Vineel Kovvuri에게


17

허용 된 답변에 대한 의견으로 Tony는 실제로 OP의 질문에 대답하는 가장 좋은 답변 인 것처럼 보였습니다 .

Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );

... 영업 이익은 않았다 NOT 을 얻는 방법을 물어 String에서 스택 추적에서 Exception. 그리고 나는 Apache Commons의 열렬한 팬이지만 위와 같은 간단한 것이있을 때 외부 라이브러리를 사용해야하는 논리적 인 이유가 없습니다.


스레드 목록이 있고 스택 추적을 인쇄해야합니다.
Daneel S. Yaitskov가

이 경우 Thread.getAllStackTraces()어느 것을 사용하는지 확인하십시오 Map<Thread, StackTraceElement[]>. 핫스팟은 하나를 보호해야 할 때마다 모든 스레드를 보호합니다. Zing은 다른 스레드를 방해하지 않고 개별 스레드를 안전한 지점으로 가져올 수 있습니다. 스택 트레이스를 얻으려면 안전 점이 필요합니다. Thread.getAllStackTraces()모든 스택 추적을 가져오고 모든 스레드를 한 번만 중지합니다. 물론, 실제로 어떤지도에 관심이 있는지 찾아야합니다.
Ralf H

14

제안합니다

  Thread.dumpStack()

더 쉬운 방법이며 실제로 문제가 발생하지 않을 때 실제로 예외를 구성하지 않거나 던질 수 없다는 이점이 있으며, 훨씬 더 중요합니다.


1
실제로 dumpStack ()은 정적 메소드이므로 정적 방식으로 액세스해야합니다. 고마워요, 일식!
토마스 Adkins

1
나는 지름길을 좋아하지만이 방법의 소스 코드는 다음과 같습니다. new Exception("Stack trace").printStackTrace();실제로 Throwable
Florent

13

스택 트레이스 얻기 :

StackTraceElement[] ste = Thread.currentThread().getStackTrace();

스택 추적 인쇄 (JAVA 8+) :

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

스택 트레이 지 인쇄 (JAVA 7) :

StringBuilder sb = new StringBuilder();

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

12

Java 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 );
}

흥미 롭군 :-)
djangofan

10

스택 추적으로 문자열을 반환하는 유틸리티 메서드가 있습니다.

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));
}

이것은 Netbeans에 의해 생성 된 하나의 자동처럼 보입니다.
Leif Gruenwoldt

로거는 내장 로거 또는 사용자가 작성하여 파일에 쓴 로거입니다.
Doug Hauf

@Doug Hauf, 로거는 내장 Java 로거에 대한 참조입니다. logging.properties 파일을 구성했는지 확인하십시오. 다음과 같이 클래스 시작 부분에 추가하십시오. private static final Logger logger = Logger.getLogger (Your_Class_Name.class.getName ());
살바도르 발렌시아

1
java.util.logging.Logger#log(Level, String, Throwable)이미이 작업을 수행합니다. 이것은 Java 표준 라이브러리에 이미 존재하는 것들을 불필요하게 다시 작성하고 있으며 새로운 개발자를 잘못된 방향으로 가리키고 있습니다. 이를 통해 Stacktrace가 특정 방식으로 포맷되도록 강요했습니다. loggingAPI를 통해 사용자가 지정한대로 로그 문의 포맷을 동적으로 변경할 수 있습니다. 내 지식으로 log4j는 비슷한 행동이 있습니다. 내가 설명 한 것과 같은 것을 잃어 버릴 수 있기 때문에 바퀴를 재발 명하지 마십시오.
searchengine27

1
2012 년에도 존재했습니다. 불행히도 날짜는 귀하의 사건에 영향을 미치지 않습니다. [link] (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)), [link] (docs.oracle.com/javase/1.5.0/docs/api/java/util/logging/Logger.html#log (java.util.logging.LogRecord)) 등 패스 몇 가지 기능입니다 Throwable받는 오프 Handler받는 사람을 통해들 Formatter보다 내가 여기에 나열된 것보다 Java7했다 2012 년에들 그리고 이러한 기능은 훨씬 더 Java7가 주변에있다보다 거슬러 올라간다;. 따라서 J2SE 5.0의 javadoc)
searchengine27을

10

구아바로 끈으로 묶기 :

Throwables.getStackTraceAsString(new Throwable())

8
try {
}
catch(Exception e) {
    StackTraceElement[] traceElements = e.getStackTrace();
    //...
}

또는

Thread.currentThread().getStackTrace()

최고의 예제는 try / catch 블록과 관련된 스택 추적 만 제공하지 않습니까?
Dan Monego

1
둘 사이의 차이점은 무엇입니까
twlkyao

5

아마도 당신은 이것을 시도 할 수 있습니다 :

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

문자열 'errorDetail'에는 스택 추적이 포함됩니다.


5
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

배열의 마지막 요소는 스택의 맨 아래를 나타내며 시퀀스에서 가장 최근의 메소드 호출입니다.

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

StackTraceElement를 반복하고 원하는 결과를 얻습니다.

for (StackTraceElement ste : stackTraceElements ) 
{
    //do your stuff here...
}

마지막 요소에 가장 최근 요소가 포함되어 있음을 언급 해 주셔서 감사합니다. 반 직관적이고 시간을 절약했습니다.
clearlight

또한 .toString ()은 모든 데이터를 문자열로 멋지게 출력합니다.
Vlad

4

위의 답변을 사용하고 형식을 추가했습니다.

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);
    }
}

2

프로세스의 현재 호출 스택을 확인하려는 경우 jstack 유틸리티를 사용할 수 있습니다.

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] [server_id@]<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

1

이것은 오래된 게시물이지만 내 해결책은 다음과 같습니다.

Thread.currentThread().dumpStack();

더 많은 정보와 더 많은 방법 : http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html


3
Thread.dumpStack ()은 정적이므로 직접 호출해야합니다.
David Avendasora

2
OP는 인쇄하지 않고 스택 추적에 대한 코드 참조를 원한다고 표시했습니다.
Taylor R

1
@DavidAvendasora가 언급했듯이 Thread.dumpStack()정적 메소드 때문에 직접 호출해야합니다 .
M-WaJeEh

예, java.lang.Thread.dumpStack ()은 Java 11에서 작동합니다.
Park JongBum

-3

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

이렇게하면 루프없이 스택 추적을 인쇄하는 데 도움이됩니다.


1
귀하의 답변은 3 개월 전에 게시 한 것과 동일합니다.
마이크 설치류
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.