9

내 응용 프로그램이 어딘가에 강제 종료를 일으키고 있지만 LogCat에서 일반적인 (매우 유익한) 스택 추적으로 치명적인 오류가 발생하는 대신 다음 4 줄만 수신합니다.캐치되지 않은 예외로 스레드가 종료 됨 : 스택 추적 없음

06-27 07:08:54.546: D/dalvikvm(14351): GC_FOR_MALLOC freed 9923 objects/657416 bytes in 21ms 
06-27 07:08:54.769: W/dalvikvm(14351): threadid=20: thread exiting with uncaught exception (group=0x4001d7f0) 
06-27 07:08:54.796: W/dalvikvm(14351): threadid=21: thread exiting with uncaught exception (group=0x4001d7f0) 
06-27 07:08:54.796: I/Process(14351): Sending signal. PID: 14351 SIG: 9 

이것은 로그 필터에 적용된 필터가없는 디버그 모드입니다!

  • 이 문제의 원인은 무엇입니까?
  • 이 예외의 원인을 알 수있는 방법이 있습니까?

업데이트 : 아래 @assylias에 덕분에, 내가 구현 할 수있었습니다 :

06-27 08:24:47.105: D/dalvikvm(15475): GC_FOR_MALLOC freed 13865 objects/1435952 bytes in 45ms 
06-27 08:24:47.136: I/dalvikvm(15475): threadid=15: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI 
06-27 08:24:47.136: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x45209338 (56 left) 
06-27 08:24:47.140: I/dalvikvm(15475): expanding stack end (0x45209300 to 0x45209000) 
06-27 08:24:47.140: I/dalvikvm(15475): Shrank stack (to 0x45209300, curFrame is 0x4520937c) 
06-27 08:24:47.159: I/dalvikvm(15475): threadid=16: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI 
06-27 08:24:47.159: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x4520c338 (56 left) 
06-27 08:24:47.167: I/dalvikvm(15475): expanding stack end (0x4520c300 to 0x4520c000) 
06-27 08:24:47.167: I/dalvikvm(15475): Shrank stack (to 0x4520c300, curFrame is 0x4520c37c) 
06-27 08:24:47.175: I/dalvikvm(15475): threadid=17: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI 
06-27 08:24:47.175: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x4520f338 (56 left) 
06-27 08:24:47.175: I/dalvikvm(15475): expanding stack end (0x4520f300 to 0x4520f000) 
06-27 08:24:47.175: I/dalvikvm(15475): Shrank stack (to 0x4520f300, curFrame is 0x4520f37c) 

이 확실히 훨씬 더 유용이 추가 라인을 생산

final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler(); 
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
    @Override 
    public void uncaughtException(Thread paramThread, Throwable paramThrowable) { 
    Log.getStackTraceString(paramThrowable); 

    subclass.uncaughtException(paramThread, paramThrowable); 
    } 
}); 

정보,하지만 지금은 다음과 고투하고있어 :

  • subclass.uncaughtException()에 대한 호출에도 불구하고 응용 프로그램이 강제 종료되지 않습니다. 왜?
  • 모든 스택 오버플로의 의미는 무엇입니까? 내 가난한 안드로이드 테스트 장치에 그렇게 과세 할 수 있을까?
  • 내 코드에서 어떤 부분이이 문제를 일으키는 지 어떻게 알 수 있습니까?

업데이트 :Log.getStackTraceString(paramThrowable); 실제로 인쇄되지 않았습니다. 받은 여분의 인쇄물은 bogus subclass.uncaughtException (paramThread, paramThrowable)에서 왔습니다. 전체 스택 추적을 기록하는 올바른 방법은 Log.e(TAG, "uncaughtException", throwable)을 사용하는 것입니다.

남은 유일한 질문은 예외를 다시 던지기위한 것입니다. throw paramThrowable을할까요?

내 마지막 질문에 답하기 : 이클립스는 try/catch를 사용하지 않고서는 내버려 둘 수 없으므로 내가 원하는 것은 다시 던지기가 아니라 killProcess()이라는 것을 알게되었다. 문제 해결됨.

+0

아마도 코드에 try catch를 사용하면 식별하는 데 도움이됩니다. –

+0

@Mukund 어디에서 코드 사용 하시겠습니까? 이미 수많은 try/catch 절을 사용하고 있습니다. –

+0

아래의 답변으로 좀더 일반적인 try catch를 추가하여 .java 파일의 전체 코드를 둘러 쌉니다. –

답변

18

:

private static void setDefaultUncaughtExceptionHandler() { 
    try { 
     Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 

      @Override 
      public void uncaughtException(Thread t, Throwable e) { 
       logger.error("Uncaught Exception detected in thread {}", t, e); 
      } 
     }); 
    } catch (SecurityException e) { 
     logger.error("Could not set the Default Uncaught Exception Handler", e); 
    } 
} 
+0

감사합니다. +1. 안드로이드는 이미 기본 잡히지 않은 예외 핸들러를 제공하고 있지만 맹세 할 수도 있습니다. 곧 [귀하의 접근 방법] (http://stackoverflow.com/a/8877177/562776)을 시도 할 것입니다. –

+1

@EternalLearner 나는 그런 경우인지 안드로이드에 익숙하지 않다. 안드로이드에 적용되는 비슷한 접근법에 대해서는 [다른 질문에 대한 답변] (http://stackoverflow.com/a/755151/829571)을 참조하십시오 (그러나 사용하기에는 너무 복잡 할 것입니다). – assylias

+0

귀하의 답변은 문제 해결 노력의 진전을 분명히 허용했기 때문에 귀하의 대답을 받아 들일 것입니다. 그러나, 나는 아직도 몇몇 문제점으로 고투하고있다. 위의 업데이트를 참조하십시오. +1. –

2

이것은 지루할 것입니다. 그러나 디버거와 충돌 할 때까지 나는 한 단계 씩 나아갈 것입니다. 그건 당신이 더 당신은 문제가있어 진단하는 데 도움이 될 수 있도록 당신은 모든 예외는 Exception에서 확장보다 일반적인 캐치

캐치 (예외 전자) { }

를 추가 할 수 있습니다.

더 많은 아이디어가 있습니다. 앱이 기기 메모리를 실행하고 있습니다. JVM이 메모리 오류로 종료되어 사용자에게 알리지 않고 앱을 종료 할 수 있습니다.

앱의 시작 부분에 기본 캐치되지 않는 예외 핸들러를 설정하고 (아래 예는 자바 로거를 사용하고 있지만 쉽게 안드로이드에 트랜스 위해) 거기에 일부 데이터를 기록 할 수
+0

예외 메시지 바로 전에 GC_FOR_MALLOC 메시지를 보내 주셔서 감사합니다. . 나는 그것이 관련이 없다고 생각했기 때문에 나는 그것을 게시하지 않았다. 이 가능성에 대해 언급 했으므로 이제 질문을 업데이트했습니다. 나는 당신의 기술이 저를 위해 작동하는지 보겠습니다. –

+0

아래 Assylias의 답변은 내 것보다 훨씬 낫습니다. 대형 앱을 통한 단일 스테핑이 너무 오래 걸릴 경우 기본 예외 처리기를 사용하는 것이 좋습니다. –

0

나는 이것을 알고 다른 사람이 잡히지 않은 예외를 처리 한 후 정상적으로 종료하는 것에 대해 알고 싶으면 다음과 같이합니다.

final Thread.UncaughtExceptionHandler androidDefaultUEH = Thread.getDefaultUncaughtExceptionHandler(); 

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
      @Override 
      public void uncaughtException(final Thread thread, final Throwable ex) { 
       // Handle exception however you want, then: 
       androidDefaultUEH.uncaughtException(thread, ex); 
      } 
     }); 
관련 문제