General ANR Diagnostic Guide

There are many questions with the ANR trace file, and the answer is always “oh, the problem is in your stream 76, fix your HTTP call” or something :) But I could not find any general guide or tutorial on how to read these traces, step by step for any ANR. Whether there is a? I have few questions, in particular:

  • Is it always possible to see the problem from the stream traces that I see for real ANRs in the Google console? Or is it possible that there is no relevant information and I’m out of luck if I cannot play ANR locally?

  • What streams are included in this information? I suppose there are all the threads from my application, but what about the rest? Are they all so important to me? (for example, threads that are waiting for some of my threads, etc.). Or are there also completely unrelated processes?

  • How the Google Play Console defines the "place" where the ANR occurred, which then appears in the ANR list, for example:

ANR keyDispatchingTimedOut

miesto: com.sample.myapp / myapp.activities.SplashActivity

Since SplashActivity is nowhere to be seen in the provided text of the stream traces.

  1. I know that I should look for threads in the WAIT state for potential deadlocks, etc. How about a situation where a thread is “waiting on itself”?

"AsyncTask # 1" prio = 5 tid = 15 WAIT | group = "main" sCount = 1 dsCount = 0 obj = 0x41bb50c0 self = 0x5529a868 | sysTid = 2448 nice = 0 sched = 0/0 cgrp = apps handle = 1429609576 | state = S schedstat = (18097077 39273309 41) utm = 1 stm = 0 core = 1 in java.lang.Object.wait (native method) - wait on <0x41bb5258> (java.lang.VMThread) held by tid = 15 ( AsyncTask # 1)

Is this always normal, and I can assume that this is not the reason? How about a situation where I only have a bunch of threads in NATIVE (including the main thread) and a bunch of threads in WAIT waiting for themselves like this? How can this be ANR?

+7
android android-anr-dialog
source share
2 answers

This is probably not the general general ANR detection recipe you are looking for, but a good start is a strict mode for your application.

You can check logcat and the system will tell you when you are doing something wrong.

Just add these lines to your Application or Activity onCreate () method:

if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectAll() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .build()); } 

More details here: http://developer.android.com/reference/android/os/StrictMode.html

+3
source share

The system sends various events to your application, which are received in the user interface stream. If this thread does not respond to events for a certain period of time, the system concludes that the application is not responding and initiates ANR processing.

Addressing your question by points:

  • It is not always possible to see the problem in the stack trace. The system server process detects that there is a problem, and then signals the problem process to reset the stack traces. If the application recovered between a problem detection and a stack dump signal, then the traces will not tell you much.

  • You should see all streams from your application and only your application. The ANR mechanism does not attempt to determine a set of "relevant" flows. The place to start is the UI thread, usually the application's “main” thread, to see if you get caught as a result of a jam. Sometimes an application runs slowly rather than getting stuck, and the reason for slowness is actually another process that soaks up the processor or disk bandwidth, but you cannot see this in the stack trace ... and you will most likely get a stack trace that reflects execution for the point where he is "stuck".

  • A “place” is an event that has not been answered (in this case, a key event) and the activity with which the system tried to interact.

  • This is normal; you will see that when the stream is “parked” through java.util.concurrent.locks.LockSupport.park() in Dalvik. Remember that the lock is released while the thread is waiting, so in this case it just waits for another thread to appear and notify it.

Addressing the point raised in the comments: it is possible for a native failure to call ANR if (1) its own failure does not completely destroy the application, which should have been done; and (2) the thread that died was a user interface thread, or contained a resource that the user interface thread was expecting. If you don't have access to the full logarithm, you can check the list of threads to confirm that all of your threads are alive.

When you look at ANR, the first thing you need to find out is that it is constantly stuck or just temporarily slowed down. This should be obvious to the person using the application. Permanent freezes are usually the easiest to solve, since stack tracing will usually lead you to what went wrong. Start with the user interface flow and walk along the track until you find some code that rotates or gets stuck in a regular call. (There is a trick with native calls, though - if it says NATIVE, then it is still in its own code, but if it says SUSPENDED in a thread with its own method at the top of the stack, then it does not get stuck, but rather in the action of returning from native into managed code.)

Transient ANRs can be more complex, especially if they occur on client devices whose configuration is unknown. If they use CPU tests in the background on a device that stops due to a flash part failure, your application will have a bad time. Sometimes the stack trace indicates the general direction of the problem (for example, this one , where it looks slow, rendering and crude blocking stop the user interface flow), in other cases, the trace is saved after the application returns to normal operation.

+3
source share

All Articles