When a process dies or freezes, Android leaves behind a detailed record. Reading it turns 'the head unit rebooted' into a specific line of code.
Advanced6 minDebugging · Crashes · ANR
Two different failures, two different investigations. A crash is a process
dying suddenly. An ANR is a process still alive but not responding. They look
similar from the driver's seat and have almost nothing in common underneath.
When C or C++ code dereferences a null pointer or overruns a buffer, the kernel
delivers a fatal signal. Android catches it and writes a — a
detailed record of the process's final state.
Finding thembash
adb shell ls -la /data/tombstones/adb pull /data/tombstones/tombstone_00# The crash summary also goes to the crash log bufferadb logcat -b crash
Without symbols, a backtrace is addresses. With them, it is function names and
line numbers.
Symbolisingbash
# Symbols come from the build that produced the crashing imageexport ANDROID_PRODUCT_OUT=~/aosp/out/target/product/vegadevelopment/scripts/stack < tombstone_00# Or directlyllvm-addr2line -Cfe $ANDROID_PRODUCT_OUT/symbols/vendor/bin/hw/vendor.vega.vehicle 0x12a4c
An is different: the process is alive and healthy, but not answering.
Android declares one when an app does not handle input within about 5 seconds, a
broadcast is not processed in time, or a service does not start quickly enough.
Finding an ANR reportbash
adb shell ls -la /data/anr/adb pull /data/anr/anr_2026-08-29-14-22-01-000adb logcat -b all | grep -i -A5 'ANR in'
An ANR trace dumps every thread in every relevant process. The main thread of
the offending app is what you want first.
A main thread that is blocked
"main" prio=5 tid=1 Native | state=S ... at android.os.BinderProxy.transactNative(Native method) at android.os.BinderProxy.transact(BinderProxy.java:584) at android.car.hardware.property.ICarProperty$Stub$Proxy.getProperty(...) at android.car.hardware.property.CarPropertyManager.getProperty(...) at com.example.SpeedGauge.onDraw(SpeedGauge.java:88)