Fehlerberichte lesen

Fehler sind bei jeder Art von Entwicklung Realität – und Fehlerberichte sind entscheidend, um Probleme zu erkennen und zu beheben. Alle Android-Versionen unterstützen die Erfassung von Fehlerberichten mit Android Debug Bridge (adb). Android-Versionen 4.2 und höher unterstützen eine Entwickleroption, mit der Fehlerberichte erstellt und per E-Mail, Drive usw. geteilt werden können.

Android-Fehlerberichte enthalten dumpsys-, dumpstate- und logcat-Daten im Textformat (.txt), sodass Sie ganz einfach nach bestimmten Inhalten suchen können. In den folgenden Abschnitten werden die Komponenten von Fehlerberichten beschrieben, häufige Probleme erläutert und hilfreiche Tipps und grep-Befehle zum Auffinden von Logs zu diesen Fehlern gegeben. Die meisten Abschnitte enthalten auch Beispiele für den grep-Befehl und die dumpsys-Ausgabe.

Logcat

Das logcat-Protokoll ist ein stringsbasierter Dump aller logcat-Informationen. Der Teil system ist für das Framework reserviert und hat eine längere Geschichte als main, der alles andere enthält. Jede Zeile beginnt in der Regel mit timestamp UID PID TID log-level. In älteren Android-Versionen wird UID möglicherweise nicht aufgeführt.

Ereignisprotokoll aufrufen

Dieses Protokoll enthält Stringdarstellungen von binärformatierten Protokollmeldungen. Es ist weniger unübersichtlich als das logcat-Protokoll, aber auch etwas schwerer zu lesen. Wenn Sie sich Ereignisprotokolle ansehen, können Sie in diesem Abschnitt nach einer bestimmten Prozess-ID (PID) suchen, um zu sehen, was ein Prozess getan hat. Das grundlegende Format ist: timestamp PID TID log-level log-tag tag-values.

Zu den Logebenen gehören:

  • V: ausführlich
  • D: Debuggen
  • I: Informationen
  • W: Warnung
  • E: Fehler

 

Weitere nützliche Ereignisprotokoll-Tags finden Sie unter /services/core/java/com/android/server/EventLogTags.logtags.

ANRs und Deadlocks

Anhand von Fehlerberichten können Sie die Ursache für „App antwortet nicht“-Fehler (ANRs) und Deadlock-Ereignisse ermitteln.

Nicht reagierende Apps identifizieren

Wenn eine Anwendung nicht innerhalb einer bestimmten Zeit reagiert, in der Regel aufgrund eines blockierten oder belegten Hauptthreads, beendet das System den Prozess und lagert den Stack in /data/anr aus. Um den Schuldigen hinter einer ANR zu finden, suchen Sie im Binärereignisprotokoll nach am_anr.

Sie können auch im logcat-Protokoll nach ANR in suchen. Dieses enthält weitere Informationen dazu, was zum Zeitpunkt der ANR die CPU beansprucht hat.

Stacktraces finden

Häufig finden Sie Stacktraces, die einem ANR entsprechen. Prüfen Sie, ob der Zeitstempel und die PID in den VM-Traces mit dem untersuchten ANR übereinstimmen, und prüfen Sie dann den Hauptthread des Prozesses. Hinweise:

  • Der Hauptthread gibt nur an, was der Thread zum Zeitpunkt des ANR-Fehlers tat. Dies entspricht möglicherweise nicht der tatsächlichen Ursache des ANR-Fehlers. Der Stack im Fehlerbericht ist möglicherweise unschuldig. Möglicherweise war etwas anderes lange Zeit blockiert, aber nicht ganz lange genug für einen ANR, bevor es sich gelöst hat.
  • Es kann mehr als ein Satz von Stack-Traces (VM TRACES JUST NOW und VM TRACES AT LAST ANR) geben. Achten Sie darauf, dass Sie sich im richtigen Bereich befinden.

Deadlocks finden

Deadlocks treten oft zuerst als ANRs auf, weil Threads hängen bleiben. Wenn der Deadlock den Systemserver betrifft, wird er vom Watchdog schließlich beendet. Dies führt zu einem Eintrag im Protokoll, der etwa so aussieht: WATCHDOG KILLING SYSTEM PROCESS. Aus Sicht des Nutzers wird das Gerät neu gestartet, obwohl es sich technisch gesehen um einen Neustart der Laufzeit handelt und nicht um einen echten Neustart.

  • Bei einem Neustart während der Laufzeit wird der Systemserver beendet und neu gestartet. Der Nutzer sieht, dass das Gerät zur Startanimation zurückkehrt.
  • Bei einem Neustart ist der Kernel abgestürzt. Der Nutzer sieht, dass das Gerät zum Google-Boot-Logo zurückkehrt.

Um Deadlocks zu finden, prüfen Sie die Abschnitte der VM-Traces auf ein Muster, bei dem Thread A auf etwas wartet, das von Thread B gehalten wird, der wiederum auf etwas wartet, das von Thread A gehalten wird.

Aktivitäten

Eine Aktivität ist eine Anwendungskomponente, die einen Bildschirm bietet, über den Nutzer Aktionen ausführen können, z. B. eine Nummer wählen, ein Foto aufnehmen oder eine E-Mail senden. Aus Sicht eines Fehlerberichts ist eine Aktivität eine einzelne, fokussierte Aktion, die ein Nutzer ausführen kann. Daher ist es sehr wichtig, die Aktivität zu ermitteln, die während eines Absturzes im Fokus stand. Aktivitäten (über ActivityManager) führen Prozesse aus. Wenn Sie also alle Prozessstopps und -starts für eine bestimmte Aktivität ermitteln, kann dies auch bei der Fehlerbehebung helfen.

Fokussierte Aktivitäten ansehen

Wenn Sie sich einen Verlauf Ihrer fokussierten Aktivitäten ansehen möchten, suchen Sie nach am_focused_activity.

Anzeigeprozess startet

Wenn Sie sich einen Verlauf der Prozessstarts ansehen möchten, suchen Sie nach Start proc.

Feststellen, ob das Gerät überlastet ist

Um festzustellen, ob das Gerät überlastet ist, prüfen Sie, ob es in kurzer Zeit zu einem ungewöhnlichen Anstieg der Aktivität um am_proc_died und am_proc_start kommt.

Arbeitsspeicher

Da Android-Geräte häufig nur wenig physischen Arbeitsspeicher haben, ist die Verwaltung des Arbeitsspeichers (RAM) entscheidend. Fehlerberichte enthalten mehrere Indikatoren für einen niedrigen Arbeitsspeicher sowie einen Dump-Status, der einen Arbeitsspeicher-Snapshot bereitstellt.

Niedrigen Arbeitsspeicher ermitteln

Ein geringer Arbeitsspeicher kann dazu führen, dass das System überlastet wird, da einige Prozesse zum Freigeben von Arbeitsspeicher beendet werden, andere Prozesse aber weiterhin gestartet werden. Wenn Sie sich bestätigende Hinweise auf einen geringen Arbeitsspeicherbedarf ansehen möchten, prüfen Sie, ob im Binärprotokollereignis viele Einträge der Typen am_proc_died und am_proc_start vorhanden sind.

Ein geringer Arbeitsspeicher kann auch den Aufgabenwechsel verlangsamen und Rückgabeversuche vereiteln, da die Aufgabe, zu der der Nutzer zurückkehren wollte, beendet wurde. Wenn der Launcher beendet wurde, wird er neu gestartet, wenn der Nutzer die Startbildschirmtaste berührt. Die Protokolle zeigen, dass der Launcher seine Inhalte neu lädt.

Bisherige Indikatoren ansehen

Der Eintrag am_low_memory im binären Ereignisprotokoll gibt an, dass der letzte im Cache befindliche Prozess beendet wurde. Danach beendet das System Dienste.

Indikatoren für Auslagerung anzeigen

Weitere Indikatoren für System-Thrashing (Auslagerung, direkte Wiederherstellung usw.) sind kswapd-, kworker- und mmcqd-Zyklen. Beachten Sie, dass der erfasste Fehlerbericht die Indikatoren für Auslagerung beeinflussen kann.

ANR-Protokolle können einen ähnlichen Arbeitsspeicher-Snapshot liefern.

Speicher-Snapshot abrufen

Der Speicher-Snapshot ist ein Dump-Status, in dem laufende Java- und native Prozesse aufgeführt sind. Weitere Informationen finden Sie unter Gesamte Speicherzuweisungen ansehen. Der Snapshot gibt nur den Status zu einem bestimmten Zeitpunkt an. Das System befand sich vor dem Snapshot möglicherweise in einem besseren (oder schlechteren) Zustand.

Übertragungen

Anwendungen generieren Broadcasts, um Ereignisse innerhalb der aktuellen Anwendung oder an eine andere Anwendung zu senden. Broadcastempfänger abonnieren bestimmte Nachrichten (über Filter), sodass sie eine Übertragung sowohl empfangen als auch darauf antworten können. Fehlerberichte enthalten Informationen zu gesendeten und nicht gesendeten Übertragungen sowie einen Dumpsys aller Empfänger, die eine bestimmte Übertragung empfangen.

Bisherige Übertragungen ansehen

Bisherige Übertragungen sind bereits gesendet und werden in umgekehrter chronologischer Reihenfolge aufgeführt.

Der Bereich Zusammenfassung enthält eine Übersicht über die letzten 300 Streams im Vordergrund und die letzten 300 Streams im Hintergrund.

Der Bereich Details enthält vollständige Informationen zu den letzten 50 Streams im Vordergrund und den letzten 50 Streams im Hintergrund sowie die Empfänger für jeden Stream. Empfänger mit folgenden Eigenschaften:

  • BroadcastFilter-Einträge werden zur Laufzeit registriert und nur an bereits laufende Prozesse gesendet.
  • ResolveInfo-Einträge werden über Manifesteinträge registriert. Der ActivityManager startet den Prozess für jede ResolveInfo, sofern er noch nicht ausgeführt wird.

Aktive Übertragungen ansehen

Als „aktiv“ gelten Übertragungen, die noch nicht gesendet wurden. Eine große Anzahl in der Warteschlange bedeutet, dass das System die Übertragungen nicht schnell genug versenden kann, um mitzuhalten.

Hörer von Übertragungen ansehen

Eine Liste der Empfänger, die auf eine Übertragung warten, finden Sie in der dumpsys activity broadcasts in der Tabelle „Receiver Resolver“. Im folgenden Beispiel werden alle Empfänger angezeigt, die auf USER_PRESENT warten.

Konflikte überwachen

Protokolle zur Monitorbelegung können manchmal auf eine tatsächliche Monitorbelegung hinweisen, aber meistens darauf, dass das System so ausgelastet ist, dass alles verlangsamt wird. Möglicherweise sehen Sie im System- oder Ereignisprotokoll lange Monitorereignisse, die von ART protokolliert wurden.

Im Systemprotokoll:

10-01 18:12:44.343 29761 29914 W art     : Long monitor contention event with owner method=void android.database.sqlite.SQLiteClosable.acquireReference() from SQLiteClosable.java:52 waiters=0 for 3.914s

Im Ereignisprotokoll:

10-01 18:12:44.364 29761 29914 I dvm_lock_sample: [com.google.android.youtube,0,pool-3-thread-9,3914,ScheduledTaskMaster.java,138,SQLiteClosable.java,52,100]

Hintergrundkompilierung

Die Kompilierung kann teuer sein und das Gerät belasten.

Die Kompilierung kann im Hintergrund erfolgen, wenn Google Play Store-Updates heruntergeladen werden. In diesem Fall werden Nachrichten von der Google Play Store App (finsky) und installd vor Nachrichten von dex2oat angezeigt.

Die Kompilierung kann auch im Hintergrund erfolgen, wenn eine Anwendung eine Dex-Datei lädt, die noch nicht kompiliert wurde. In diesem Fall werden keine finsky- oder installd-Protokolle ausgegeben.

Hintergrundinformationen

Um die Geschichte eines Problems zu ermitteln (wie es angefangen hat, was passiert ist, wie das System reagiert hat), ist eine solide Zeitachse der Ereignisse erforderlich. Mit den Informationen im Fehlerbericht können Sie Zeitachsen in mehreren Protokollen synchronisieren und den genauen Zeitstempel des Fehlerberichts ermitteln.

Zeitpläne synchronisieren

Ein Fehlerbericht enthält mehrere parallele Zeitachsen: Systemprotokoll, Ereignisprotokoll, Kernelprotokoll und mehrere spezielle Zeitachsen für Übertragungen, Akkustatistiken usw. Leider werden Zeitachsen oft mit unterschiedlichen Zeitbasen erfasst.

Die Zeitstempel für das System und das Ereignisprotokoll sind in derselben Zeitzone wie die des Nutzers (wie die meisten anderen Zeitstempel). Wenn der Nutzer beispielsweise auf die Startbildschirmschaltfläche tippt, wird im Systemprotokoll Folgendes protokolliert:

10-03 17:19:52.939  1963  2071 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL (has extras)} from uid 1000 on display 0

Für dieselbe Aktion wird im Ereignisprotokoll Folgendes protokolliert:

10-03 17:19:54.279  1963  2071 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]

Kernel-Logs (dmesg) verwenden eine andere Zeitbasis. Logelemente werden mit Sekunden seit Abschluss des Bootloaders getaggt. Wenn Sie diese Zeitachse für andere Zeitachsen registrieren möchten, suchen Sie nach den Nachrichten suspend exit und suspend entry:

<6>[201640.779997] PM: suspend exit 2015-10-03 19:11:06.646094058 UTC
…
<6>[201644.854315] PM: suspend entry 2015-10-03 19:11:10.720416452 UTC

Da Kernelprotokolle möglicherweise keine Zeit während des Ruhemodus enthalten, sollten Sie das Protokoll zwischen den Ein- und Ausstiegsmeldungen für den Ruhemodus stückweise erfassen. Außerdem wird in Kernel-Protokollen die Zeitzone UTC verwendet und muss an die Zeitzone des Nutzers angepasst werden.

Zeit des Fehlerberichts angeben

Wenn Sie wissen möchten, wann ein Fehlerbericht erstellt wurde, prüfen Sie zuerst das Systemprotokoll (Logcat) für die dumpstate: begin:

10-03 17:19:54.322 19398 19398 I dumpstate: begin

Prüfen Sie als Nächstes die Zeitstempel im Kernel-Log (dmesg) auf die Starting service 'bugreport'-Nachricht:

<5>[207064.285315] init: Starting service 'bugreport'...

Gehen Sie rückwärts vor, um die beiden Ereignisse zu korrelieren. Beachten Sie dabei die Einschränkungen, die unter Zeitachsen synchronisieren erwähnt wurden. Nach dem Starten des Fehlerberichts passiert zwar viel, die meisten Aktivitäten sind jedoch nicht sehr nützlich, da das System durch die Aufnahme des Fehlerberichts stark belastet wird.

Leistung

Das Ereignisprotokoll enthält den Displaystatus. „0“ steht für „Display aus“, „1“ für „Display an“ und „2“ für „Keyguard beendet“.

Fehlerberichte enthalten auch Statistiken zu Wakelocks, einem Mechanismus, mit dem App-Entwickler angeben, dass ihre App das Gerät eingeschaltet lassen muss. Weitere Informationen zu Wakelocks finden Sie unter PowerManager.WakeLock und CPU eingeschaltet lassen.

Die zusammengefassten Statistiken zur Dauer des Wakelocks erfassen nur die Zeit, in der ein Wakelock tatsächlich dafür verantwortlich ist, das Gerät aktiv zu halten. Die Zeit, in der das Display eingeschaltet ist, wird nicht berücksichtigt. Wenn mehrere Wakelocks gleichzeitig gehalten werden, wird die Dauer des Wakelocks auf diese Wakelocks verteilt.

Weitere Informationen zur Visualisierung des Energiestatus finden Sie unter Battery Historian, einem Open-Source-Tool von Google, mit dem Sie Akkuverbraucher anhand von Android-Fehlerberichtsdateien analysieren können.

Pakete

Der Abschnitt DUMP OF SERVICE package enthält Anwendungsversionen und andere nützliche Informationen.

Prozesse

Fehlerberichte enthalten eine große Menge an Daten zu Prozessen, einschließlich Start- und Endzeit, Laufzeit, verknüpften Diensten und oom_adj-Wert. Weitere Informationen zur Verwaltung von Prozessen unter Android finden Sie unter Prozesse und Threads.

Prozesslaufzeit ermitteln

Der Abschnitt procstats enthält vollständige Statistiken dazu, wie lange Prozesse und zugehörige Dienste ausgeführt wurden. Wenn Sie eine schnelle, visuell ansprechende Zusammenfassung sehen möchten, suchen Sie nach AGGREGATED OVER, um Daten aus den letzten drei oder 24 Stunden aufzurufen. Suchen Sie dann nach Summary:, um eine Liste der Prozesse, die Dauer, in der diese Prozesse mit verschiedenen Prioritäten ausgeführt wurden, und die RAM-Nutzung im Format „min-Durchschnitt-max PSS/min-Durchschnitt-max USS“ aufzurufen.

Gründe für einen laufenden Prozess

Im Bereich dumpsys activity processes werden alle derzeit laufenden Prozesse nach oom_adj-Wert sortiert aufgelistet. Android gibt die Prozessbedeutung an, indem dem Prozess ein oom_adj-Wert zugewiesen wird, der von ActivityManager dynamisch aktualisiert werden kann. Die Ausgabe ähnelt der eines Arbeitsspeicher-Snapshots, enthält aber zusätzliche Informationen dazu, was den Prozess auslöst. Im folgenden Beispiel geben die fett formatierten Einträge an, dass der Prozess gms.persistent mit der (sichtbaren) Priorität vis ausgeführt wird, da der Systemprozess an seine NetworkLocationService gebunden ist.

Scans

So identifizieren Sie Anwendungen, die zu viele Bluetooth Low Energy (BLE)-Scans ausführen:

  • So finden Sie Protokollmeldungen für BluetoothLeScanner:
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • Suchen Sie in den Lognachrichten nach der PID. In diesem Beispiel sind „24840“ und „24851“ die PID (Prozess-ID) und die TID (Thread-ID).
  • Suchen Sie die Anwendung, die mit der PID verknüpft ist:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    

    In diesem Beispiel lautet der Paketname com.badapp.

  • Suchen Sie den Paketnamen bei Google Play, um die verantwortliche Anwendung zu ermitteln: https://play.google.com/store/apps/details?id=com.badapp.

Hinweis: Auf Geräten mit Android 7.0 erhebt das System Daten für BLE-Scans und verknüpft diese Aktivitäten mit der auslösenden Anwendung. Weitere Informationen finden Sie unter Low Energy (LE) und Bluetooth-Scans.