디버그 에이전트 없이는 NullPointerException 스택 추적을 사용할 수 없습니다.
최근에 NullPointerException을 일으키는 버그를 발견했습니다. 예외는 표준 slf4j 문을 사용하여 포착되고 기록됩니다. 아래 요약 된 코드 :
for(Action action : actions.getActions()) {
try {
context = action.execute(context);
} catch (Exception e) {
logger.error("...", e);
break;
}
}
보시다시피 멋진 것은 없습니다. 그러나 우리가 가지고있는 모든 예외 로깅 문 중에서이 문만 스택 추적을 인쇄하지 않습니다. 출력되는 것은 메시지 ( "..."로 표시)와 예외 클래스의 이름 (java.lang.NullPointerException)뿐입니다.
예외에 대한 스택 추적이 지연로드 되었기 때문에 일종의 명령 재정렬 문제가있을 수 있다고 생각하고 로그 문 전에 e.getStackTrace ()를 호출하기로 결정했습니다. 이것은 차이가 없었습니다.
그래서 디버그 에이전트를 활성화 한 상태에서 다시 시작하기로 결정했습니다. 그러나 프로세스에 연결하기까지했기 때문에 이제 스택 트레이스가 인쇄되고 있음을 알았습니다. 따라서 디버그 에이전트의 존재로 인해 일부 추가 디버그 정보를 사용할 수있게되었습니다.
그 이후로 예외의 근본 원인을 수정했습니다. 하지만 디버거없이 스택 추적을 사용할 수없는 이유를 알고 싶습니다. 아는 사람 있어요?
설명 : 이것은 로깅 문제가 아닙니다 . 동일한 try / catch 절을 상상해보십시오. 그러나 catch에서 다음 값을 인쇄합니다.
e.getStackTrace().length
디버거가 없으면 '0'을 인쇄하고 디버거를 사용하면 양수 (이 경우 9)를 인쇄합니다.
추가 정보 : 이것은 JDK 1.6.0_13, 64bit, amd64, linux 2.6.9에서 발생합니다.
이 코드가 내부 루프에있을 수 있습니까? 그런 다음 JIT 컴파일러가 이에 대한 호출 스택을 네이티브 코드로 컴파일하여 스택 정보를 잃을 수 있습니다. 그런 다음 디버거를 연결하면 JIT가 비활성화되어 정보를 다시 사용할 수 있습니다.
다른 수동 예외는 JIT가 최적화되지 않기 때문에 정보를 계속 표시합니다.
102 행에있는이 클래스 소스 코드의 주석에서 다른 사용자에게 때때로 이런 일이 발생할 수 있습니다.
http://logging.apache.org/log4j/1.2/xref/org/apache/log4j/spi/LocationInfo.html
JVM 플래그 -XX : -OmitStackTraceInFastThrow를 사용하여이 사용 사례에 대해 JVM의 성능 최적화를 비활성화 할 수 있습니다. 플래그를 비활성화하는이 매개 변수가 제공되면 스택 추적을 사용할 수 있습니다.
자세한 내용은 다음 릴리스 정보를 참조하십시오.
"서버 VM의 컴파일러는 이제 모든"콜드 "기본 제공 예외에 대해 올바른 스택 역 추적을 제공합니다. 성능상의 이유로 이러한 예외가 몇 번 발생하면 메서드가 재 컴파일 될 수 있습니다. 재 컴파일 후 컴파일러는 다음을 선택할 수 있습니다. 스택 추적을 제공하지 않는 사전 할당 된 예외를 사용하는 더 빠른 전술. 사전 할당 된 예외의 사용을 완전히 비활성화하려면 다음 새 플래그를 사용하십시오. -XX : -OmitStackTraceInFastThrow. " http://java.sun.com/j2se/1.5.0/relnotes.html
나는 이것을 복제 할 수 있지만 이것이 당신의 액션 어딘가에서 일어나는 것이 이상하게 보입니다.
빈 배열로 setStackTrace를 호출하면 텍스트 만 표시됩니다.
public class Fark {
public static void main(String[] args) {
try {
Fark.throwMe(args.length != 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static final void throwMe(boolean arg) throws Exception{
Exception e = new NullPointerException();
if (arg) {
e.setStackTrace(new StackTraceElement[0]);
}
throw e;
}
}
실행 중 ....
% java Fark
java.lang.NullPointerException
at Fark.throwMe(Fark.java:15)
at Fark.main(Fark.java:5)
% java Fark nothing
java.lang.NullPointerException
'IT TIP' 카테고리의 다른 글
Angular2에서 여러 경로 매개 변수 전달 (0) | 2020.12.11 |
---|---|
Excel에서 셀을 보호하지만 VBA 스크립트로 수정 가능 (0) | 2020.12.11 |
무료 DTD에서 XSD 로의 변환 유틸리티? (0) | 2020.12.11 |
특히 Fugitive의 경우 vim에서 vimdiff 모드를 어떻게 종료합니까? (0) | 2020.12.11 |
프로그램 내부에서 gdb를 호출하여 스택 추적을 인쇄하는 가장 좋은 방법은 무엇입니까? (0) | 2020.12.11 |