[java] Java에서 예외를 발생시키지 않고 스택 추적을 덤프하는 방법이 있습니까?

Java 응용 프로그램을위한 디버그 도구를 만들려고합니다.

Exception.printStackTrace()실제로 예외를 throw하지 않고 스택 추적을 얻을 수 있는지 궁금합니다 .

내 목표는 주어진 메소드에서 스택을 덤프하여 메소드 호출자가 누구인지 확인하는 것입니다.



답변

또한 Thread.getAllStackTraces()살아있는 모든 스레드에 대한 스택 추적 맵을 얻으 려고 시도 할 수 있습니다 .


답변

예, 간단히 사용하십시오

Thread.dumpStack()


답변

Ram의 제안과 같이 시스템의 모든 스레드가 아닌 현재 스레드에 대한 추적을 원한다면 다음을 수행하십시오.

Thread.currentThread (). getStackTrace ()

발신자를 찾으려면 다음을 수행하십시오.

private String getCallingMethodName() {
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
    return callingFrame.getMethodName();
}

그리고 호출자가 누구인지 알아야하는 메소드 내에서 해당 메소드를 호출하십시오. 그러나 경고 단어 : 목록 내 호출 프레임의 색인은 JVM에 따라 다를 수 있습니다! 추적이 생성되는 지점에 도달하기 전에 getStackTrace 내에있는 호출 계층 수에 따라 다릅니다. 보다 강력한 솔루션은 추적을 가져 와서 getCallingMethodName에 대한 프레임을 찾은 후 반복하여 진정한 호출자를 찾기위한 것입니다.


답변

다음과 같은 스택 추적을 얻을 수 있습니다.

Throwable t = new Throwable();
t.printStackTrace();

프레임에 액세스하려면 t.getStackTrace ()를 사용하여 스택 프레임의 배열을 얻을 수 있습니다.

핫스팟 컴파일러가 작업 최적화에 바쁘면이 스택 추적 (다른 것과 마찬가지로)에 일부 프레임이 누락 될 수 있습니다.


답변

Thread.dumpStack ()은 실제로 예외를 발생시킵니다.

new Exception("Stack trace").printStackTrace();


답변

프로세스에 QUIT 신호를 보내 실행중인 Java 프로세스에서 Thread.getAllStackTraces ()를 실행하도록 신호를 JVM에 보낼 수도 있습니다.

유닉스 / 리눅스에서 :

kill -QUIT process_id여기서 process_id는 Java 프로그램의 프로세스 번호입니다.

Windows에서는 콘솔 프로세스를 실행하지 않으면 일반적으로 표시되지 않지만 응용 프로그램에서 Ctrl-Break를 누를 수 있습니다.

JDK6에는 컴퓨터에서 실행중인 JDK6 프로세스의 스택을 표시하는 또 다른 옵션 인 jstack 명령이 도입되었습니다.

jstack [-l] <pid>

이 옵션은 프로덕션 환경에서 실행되고 쉽게 수정할 수없는 응용 프로그램에 매우 유용합니다. 런타임 교착 상태 또는 성능 문제를 진단하는 데 특히 유용합니다.

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/
http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html


답변

캡처 출력이 필요한 경우

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