2012-06-27 41 views
9

Ứng dụng của tôi đang gây ra một lực lượng ở đâu đó nhưng thay vì nhận được một ngoại lệ FATAL với dấu vết stack thông thường (và rất nhiều thông tin) trong LogCat, tôi chỉ nhận được 4 dòng sau:thread exiting with uncaught exception: NO stack trace

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 

Đây là chế độ DEBUG với NO FILTERS được áp dụng trên LogCat!

  • Điều gì có thể gây ra hành vi này?
  • Có cách nào để biết nguyên nhân gây ra ngoại lệ này không?

Cập nhật: Nhờ @assylias dưới đây, tôi đã có thể thực hiện:

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

nào sản xuất những dòng này nói thêm:

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) 

Điều này chắc chắn là nhiều hơn nữa hữu ích thông tin, nhưng bây giờ tôi đang đấu tranh với những điều sau đây:

  • Ứng dụng không bắt buộc đóng ngay bây giờ, mặc dù cuộc gọi đến subclass.uncaughtException(). Tại sao?
  • Ý nghĩa của tất cả những ngăn xếp ngăn xếp đó là gì? Tôi có thể làm gì để đánh thuế trên thiết bị thử nghiệm Android kém của mình?
  • Làm cách nào để biết phần nào trong mã của tôi gây ra điều này?

Cập nhật:Log.getStackTraceString(paramThrowable); không thực sự in bất kỳ thứ gì. Bản in bổ sung mà tôi nhận được là từ bogus subclass.uncaughtException (paramThread, paramThrowable); Cách đúng để ghi lại dấu vết ngăn xếp đầy đủ là sử dụng Log.e(TAG, "uncaughtException", throwable).

Câu hỏi duy nhất còn lại bây giờ là làm thế nào để tôi ném lại ngoại lệ? Chỉ cần làm một throw paramThrowable?

Trả lời câu hỏi cuối cùng của tôi: Eclipse sẽ không để tôi ném mà không xung quanh với try/catch, điều này khiến tôi hiểu rằng những gì tôi muốn không phải là ném lại mà là killProcess(). Đã giải quyết được sự cố.

+0

Có thể sử dụng try catch cho mã của bạn sẽ giúp xác định. –

+0

@Mukund Ở đâu trong mã của tôi? Tôi đã sử dụng nhiều mệnh đề try/catch trên khắp nơi. –

+0

Thêm một cách tổng quát hơn thử nắm bắt như câu trả lời bên dưới, bao quanh toàn bộ mã trong tệp .java. –

Trả lời

18

Bạn có thể thiết lập một handler ngoại lệ còn tự do mặc định ở phần đầu của ứng dụng của bạn và đăng nhập một số dữ liệu trong đó (ví dụ dưới đây được sử dụng một logger java nhưng dễ dàng để transpose để Android):

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

Cảm ơn +1. Tôi có thể thề rằng Android đã cung cấp một trình xử lý ngoại lệ chưa được xử lý mặc định nhưng tôi có thể bị nhầm lẫn. Tôi sẽ thử [cách tiếp cận của bạn] (http://stackoverflow.com/a/8877177/562776) ngay. –

+1

@EternalLearner Tôi không quen thuộc với Android để biết nếu đó là trường hợp. Xem [câu trả lời này cho một câu hỏi khác] (http://stackoverflow.com/a/755151/829571) cho một cách tiếp cận tương tự được áp dụng cho Android (nhưng có lẽ quá phức tạp để bạn sử dụng!). – assylias

+0

Câu trả lời của bạn sẽ được chấp nhận vì nó cho phép tôi thực hiện một cách rõ ràng trong các nỗ lực khắc phục sự cố của tôi. Tuy nhiên, tôi vẫn đang đấu tranh với một số vấn đề. Xem cập nhật của tôi ở trên. +1. –

2

điều này sẽ rất tẻ nhạt, nhưng tôi sẽ thực hiện một bước cho đến khi nó ngắt với trình gỡ lỗi. sau đó bạn có thể thêm một nắm bắt tổng quát hơn

catch (Exception e) {}

Tất cả các trường hợp ngoại lệ kéo dài từ ngoại lệ để có thể giúp bạn thêm chẩn đoán bạn đang có vấn đề.

Một ý tưởng nữa, có lẽ ứng dụng của bạn đang chạy bộ nhớ thiết bị. JVM có thể đang giết bạn là ứng dụng mà không thông báo cho bạn vì lỗi JVM bị tắt do lỗi bộ nhớ.

+0

Cảm ơn +1 vì đã chuyển sự chú ý của tôi thành tin nhắn GC_FOR_MALLOC ngay trước các thông báo ngoại lệ . Tôi không nghĩ nó có liên quan nên tôi không đăng nó. Bây giờ bạn đã đề cập đến khả năng này, tôi đã cập nhật câu hỏi của mình. Tôi sẽ xem liệu kỹ thuật của bạn có hiệu quả với tôi hay không. –

+0

Câu trả lời của Assylias dưới đây, tốt hơn nhiều so với tôi. trình xử lý ngoại lệ mặc định là một ý tưởng hay nếu bước đơn qua ứng dụng lớn sẽ mất quá nhiều thời gian. –

0

Tôi biết điều này cũ nhưng nếu bất kỳ ai khác muốn biết về việc thoát như bình thường sau khi giải quyết ngoại lệ không bị bắt buộc:

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