5

I'm trying to chase some ANRs without any stack traces. I'm at a point where I just want to review every part of my code that uses the UI thread heavily.

Is there a way to graph this or do some sort of trace to see which methods took the longest without me modifying a ton of code?

casolorz
  • 8,486
  • 19
  • 93
  • 200
  • https://stackoverflow.com/questions/704311/android-how-do-i-investigate-an-anr . or u can try https://developer.android.com/studio/profile/cpu-profiler i guess.. – ADM Mar 31 '22 at 04:56
  • I've already fixed most ANRs for which I have some detail and are fixable. My main ANRs left over have no stack traces. That is why I need some way to analyze which parts of the code are taking too long to run. The CPU profiler looks interesting, I'll have to see if it gives me anything useful. – casolorz Mar 31 '22 at 12:38

2 Answers2

7

First thing you can do is enable StrictMode. That will detect non-UI, potentially long operations running on the main thread.

Second thing you can do is profile the CPU, as stated above. You'll be able to see the activity per thread, so you can determine what is running where. In order to get accurate readings, don't run it from Android Studio. Run it directly from your code. The easiest way to do that is to use the Debug class, and start the sampling at the Application.onCreate && finish it when the app closes.

The third thing you can do is to observe the messages sent to the main thread looper and evaluate them. Pierre-Yves Ricau has a nice guide about this that you can adapt to your own processes.

After that, you can use custom approaches to evaluate critical parts of your code, like generating your own traces. Perfetto uses JSON files, so you can print logcat messages from the parts you suspect are causing trouble and parse those messages into a perfetto trace.

Mahfuza Mohona
  • 111
  • 3
  • 12
Fco P.
  • 2,486
  • 17
  • 20
1

First, you didn't mention if the code is only java or jni.

In any case, my following comment is a partial reply, since it's not about finding the longest running functions, but rather about debugging ANRs in general.

When debugging ANRs, I would handle it like a deadlock. When seeing the app is stuck, try to dump the current stack traces. It might work better than the regular ANR traces.

Another thing you can do, is attach the debugger and pause the app when you see it stuck.

The final thing to try, would be to add logs around your code when going in and out of function calls, and see the last one that went in but didn't go out. You can also try following this.

Itay Bianco
  • 697
  • 6
  • 16
  • My code is java/kotlin but there might be parts of other libraries that are jni. I should have specified a bit more but these aren't ANRs that I can reproduce myself, just what the console shows me and unfortunately it doesn't give me stack traces. – casolorz Apr 25 '22 at 20:11
  • You could try adding a watchdog. A thread that would send a message through the ui thread to update a variable which you read regularly from the thread. If it doesn't change for a few seconds, dump all threads. – Itay Bianco Apr 27 '22 at 04:42
  • Also, it isn't clear, but did you check the actual anr files through adb? Not just logcat – Itay Bianco Apr 27 '22 at 04:44
  • Like I said, I haven't gotten any of the ANRs myself. The Play Store Console reports them but without a stack trace. – casolorz Apr 28 '22 at 18:10
  • In that case, a watchdog thread would be the best bet imo. Doesn't have to cause a crash. Might send the current stack trace to some analytics service. – Itay Bianco Apr 29 '22 at 19:24