IT TIP

디버그 에이전트 없이는 NullPointerException 스택 추적을 사용할 수 없습니다.

itqueen 2020. 12. 11. 21:08
반응형

디버그 에이전트 없이는 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

참고URL : https://stackoverflow.com/questions/1076191/nullpointerexception-stack-trace-not-available-without-debug-agent

반응형