Czytanie raportów o błędach

Błędy są rzeczywistością w każdym rodzaju rozwoju — a raporty o błędach mają kluczowe znaczenie dla identyfikowania i rozwiązywania problemów. Wszystkie wersje Androida obsługują przechwytywanie raportów o błędach za pomocą Android Debug Bridge (adb) ; Wersje Androida 4.2 i nowsze obsługują opcję programisty do zgłaszania błędów i udostępniania za pośrednictwem poczty e-mail, Dysku itp.

Raporty o błędach systemu Android zawierają dane dumpsys , dumpstate i logcat w formacie tekstowym (.txt), co umożliwia łatwe wyszukiwanie określonej treści. Poniższe sekcje szczegółowo opisują składniki raportów o błędach, opisują typowe problemy oraz zawierają pomocne wskazówki i polecenia grep dotyczące znajdowania dzienników powiązanych z tymi błędami. Większość sekcji zawiera również przykłady komendy i danych wyjściowych grep i/lub danych wyjściowych dumpsys .

Logcat

Dziennik logcat jest opartym na ciągach zrzutem wszystkich informacji logcat . Część systemowa jest zarezerwowana dla frameworka i ma dłuższą historię niż główna , która zawiera wszystko inne. Każdy wiersz zwykle zaczyna się od timestamp UID PID TID log-level , chociaż identyfikator UID może nie być wymieniony w starszych wersjach Androida.

Przeglądanie dziennika zdarzeń

Ten dziennik zawiera ciągi reprezentujące komunikaty dziennika w formacie binarnym. Jest mniej hałaśliwy niż logcat , ale też trochę trudniejszy do odczytania. Przeglądając dzienniki zdarzeń, możesz przeszukać tę sekcję pod kątem określonego identyfikatora procesu (PID), aby zobaczyć, co robił proces. Podstawowy format to: timestamp PID TID log-level log-tag tag-values .

Poziomy dziennika obejmują:

  • V: gadatliwy
  • D: debugowanie
  • Ja: informacja
  • W: ostrzeżenie
  • E: błąd

Inne przydatne tagi dziennika zdarzeń znajdziesz w /services/core/java/com/android/server/EventLogTags.logtags .

Błędy ANR i zakleszczenia

Raporty o błędach mogą pomóc w zidentyfikowaniu, co powoduje błędy aplikacji nie odpowiada (ANR) i zdarzenia zakleszczenia.

Identyfikowanie nieodpowiadających aplikacji

Gdy aplikacja nie odpowiada w określonym czasie, zwykle z powodu zablokowanego lub zajętego wątku głównego, system zabija proces i zrzuca stos do /data/anr . Aby odkryć sprawcę błędu ANR, grep dla am_anr w binarnym dzienniku zdarzeń.

Możesz także grep dla ANR in dzienniku logcat , który zawiera więcej informacji o tym, co używało procesora w czasie ANR.

Znajdowanie śladów stosu

Często można znaleźć ślady stosu odpowiadające ANR. Upewnij się, że znacznik czasu i PID w śladach maszyny wirtualnej są zgodne z badanym ANR, a następnie sprawdź główny wątek procesu. Pamiętać:

  • Główny wątek informuje tylko o tym, co wątek robił w momencie wystąpienia błędu ANR, co może, ale nie musi odpowiadać prawdziwej przyczynie błędu ANR. (Stos w zgłoszeniu błędu może być niewinny; coś innego mogło utknąć przez długi czas — ale nie na tyle długo, aby ANR — zanim się odkleiło).
  • Może istnieć więcej niż jeden zestaw śladów stosu ( VM TRACES JUST NOW i VM TRACES AT LAST ANR ). Upewnij się, że przeglądasz właściwą sekcję.

Znajdowanie zakleszczeń

Zakleszczenia często pojawiają się najpierw jako błędy ANR, ponieważ wątki utknęły. Jeśli zakleszczenie dojdzie do serwera systemowego, watchdog w końcu go zabije, prowadząc do wpisu w dzienniku podobnego do: WATCHDOG KILLING SYSTEM PROCESS . Z perspektywy użytkownika urządzenie uruchamia się ponownie, chociaż technicznie jest to ponowne uruchomienie środowiska wykonawczego, a nie prawdziwy restart.

  • Podczas restartu środowiska wykonawczego serwer systemowy umiera i jest restartowany; użytkownik widzi, jak urządzenie powraca do animacji rozruchu.
  • Podczas restartu jądro uległo awarii; użytkownik widzi, że urządzenie powraca do logo rozruchowego Google.

Aby znaleźć zakleszczenia, sprawdź sekcje śledzenia maszyn wirtualnych pod kątem wzorca wątku A oczekującego na coś przechowywanego przez wątek B, który z kolei czeka na coś przechowywanego przez wątek A.

Zajęcia

Aktywność to komponent aplikacji, który zapewnia użytkownikom interakcję z ekranem w celu wykonania czegoś, na przykład wybrania numeru, zrobienia zdjęcia, wysłania wiadomości e-mail itp. Z perspektywy zgłaszania błędów działanie to pojedyncza, skoncentrowana rzecz, którą użytkownik może zrobić , co sprawia, że ​​bardzo ważne jest zlokalizowanie czynności, na której skupiano się podczas wypadku. Działania (poprzez ActivityManager) uruchamiają procesy, więc zlokalizowanie wszystkich zatrzymań i uruchomień procesów dla danego działania może również pomóc w rozwiązywaniu problemów.

Przeglądanie skoncentrowanych działań

Aby wyświetlić historię ukierunkowanych działań, wyszukaj am_focused_activity .

Rozpoczyna się proces przeglądania

Aby wyświetlić historię uruchomień procesów, wyszukaj Start proc .

Czy urządzenie się wali?

Aby określić, czy urządzenie się przewraca , sprawdź w krótkim czasie, czy wokół am_proc_died i am_proc_start nie obserwuje się nienormalnego wzrostu aktywności.

Pamięć

Ponieważ urządzenia z systemem Android często mają ograniczoną pamięć fizyczną, zarządzanie pamięcią o dostępie swobodnym (RAM) ma kluczowe znaczenie. Raporty o błędach zawierają kilka wskaźników małej ilości pamięci, a także stan zrzutu, który zapewnia migawkę pamięci.

Identyfikowanie małej pamięci

Mała ilość pamięci może powodować awarię systemu, ponieważ zabija niektóre procesy, aby zwolnić pamięć, ale kontynuuje uruchamianie innych procesów. Aby wyświetlić potwierdzające dowody małej ilości pamięci, sprawdź koncentrację wpisów am_proc_died i am_proc_start w binarnym dzienniku zdarzeń.

Mała pamięć może również spowolnić przełączanie zadań i udaremnić próby powrotu (ponieważ zadanie, do którego użytkownik próbował wrócić, zostało zabite). Jeśli program uruchamiający został zabity, uruchamia się ponownie, gdy użytkownik dotknie przycisku głównego, a dzienniki pokazują, że program uruchamiający ponownie ładuje swoją zawartość.

Przeglądanie wskaźników historycznych

Wpis am_low_memory w binarnym dzienniku zdarzeń wskazuje, że ostatni proces w pamięci podręcznej nie działał. Następnie system zaczyna zabijać usługi.

Przeglądanie wskaźników młócenia

Inne wskaźniki thrashingu systemu (stronicowanie, bezpośrednie odzyskiwanie itp.) obejmują cykle zużywające kswapd , kworker i mmcqd . (Pamiętaj, że gromadzony raport o błędach może wpływać na wskaźniki thrashingu).

Dzienniki ANR mogą zapewnić podobną migawkę pamięci.

Uzyskiwanie migawki pamięci

Migawka pamięci to stan zrzutu, który zawiera listę uruchomionych procesów Java i procesów natywnych (aby uzyskać szczegółowe informacje, zobacz Wyświetlanie ogólnych przydziałów pamięci ). Pamiętaj, że migawka podaje tylko stan w określonym momencie; system mógł być w lepszym (lub gorszym) stanie przed wykonaniem migawki.

  • Aby zrozumieć, jak długo działa proces, zobacz Środowisko uruchomieniowe procesu .
  • Aby zrozumieć, dlaczego coś jest aktualnie uruchomione, zobacz Dlaczego działa proces?

Transmisje

Aplikacje generują transmisje w celu wysyłania zdarzeń w bieżącej aplikacji lub do innej aplikacji. Odbiorniki audycji subskrybują określone wiadomości (poprzez filtry), umożliwiając im zarówno słuchanie, jak i odpowiadanie na audycję. Raporty o błędach zawierają informacje o wysłanych i niewysłanych transmisjach, a także zrzuty danych wszystkich odbiorników nasłuchujących konkretnej transmisji.

Oglądanie transmisji historycznych

Transmisje historyczne to te, które zostały już wysłane, wymienione w odwrotnej kolejności chronologicznej.

Sekcja podsumowania to przegląd ostatnich 300 transmisji na pierwszym planie i ostatnich 300 transmisji w tle.

Sekcja szczegółów zawiera pełne informacje o ostatnich 50 transmisjach na pierwszym planie i ostatnich 50 transmisjach w tle, a także o odbiornikach każdej transmisji. Odbiorniki posiadające:

  • Wpisy BroadcastFilter są rejestrowane w czasie wykonywania i są wysyłane tylko do już uruchomionych procesów.
  • ResolveInfo są rejestrowane poprzez wpisy manifestu. ActivityManager rozpoczyna proces dla każdego ResolveInfo , jeśli jeszcze nie jest uruchomiony.

Oglądanie aktywnych transmisji

Transmisje aktywne to te, które nie zostały jeszcze wysłane. Duża liczba w kolejce oznacza, że ​​system nie może wysyłać transmisji wystarczająco szybko, aby nadążyć.

Oglądanie słuchaczy transmisji

Aby wyświetlić listę odbiorników nasłuchujących transmisji, sprawdź tabelę Receiver Resolver w dumpsys activity broadcasts . Poniższy przykład wyświetla wszystkie odbiorniki nasłuchujące USER_PRESENT .

Monitoruj spór

Rejestrowanie rywalizacji o monitor może czasami wskazywać na rzeczywisty rywalizację monitora, ale najczęściej wskazuje, że system jest tak obciążony, że wszystko uległo spowolnieniu. Możesz zobaczyć długie zdarzenia monitora zarejestrowane przez ART w systemie lub dzienniku zdarzeń.

W dzienniku systemowym:

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

W dzienniku zdarzeń:

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]

Kompilacja w tle

Kompilacja może być kosztowna i obciążać urządzenie.

Kompilacja może odbywać się w tle podczas pobierania aktualizacji ze sklepu Google Play. W takim przypadku komunikaty z aplikacji sklepu Google Play ( finsky ) i installd pojawiają się przed komunikatami dex2oat .

Kompilacja może również wystąpić w tle, gdy aplikacja ładuje plik dex, który nie został jeszcze skompilowany. W takim przypadku nie zobaczysz finsky ani installd rejestrowania.

Narracja

Ustalenie narracji problemu (jak się zaczął, co się stało, jak zareagował system) wymaga solidnego harmonogramu wydarzeń. Możesz użyć informacji zawartych w raporcie o błędzie, aby zsynchronizować osie czasu w wielu dziennikach i określić dokładną sygnaturę czasową raportu o błędzie.

Synchronizowanie osi czasu

Raport o błędach odzwierciedla wiele równoległych osi czasu: dziennik systemowy, dziennik zdarzeń, dziennik jądra i wiele wyspecjalizowanych osi czasu dla transmisji, statystyk baterii itp. Niestety, osie czasu są często zgłaszane przy użyciu różnych podstaw czasowych.

Sygnatury czasowe systemu i dziennika zdarzeń znajdują się w tej samej strefie czasowej co użytkownik (podobnie jak większość innych sygnatur czasowych). Na przykład, gdy użytkownik naciśnie przycisk home, dziennik systemowy raportuje:

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

W przypadku tej samej akcji dziennik zdarzeń raportuje:

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

Dzienniki jądra ( dmesg ) używają innej podstawy czasu, oznaczając elementy dziennika sekundami od zakończenia bootloadera. Aby zarejestrować tę skalę czasową w innych skalach czasowych, wyszukaj komunikaty zawieszenia wyjścia i zawieszenia wejścia :

<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

Ponieważ dzienniki jądra mogą nie uwzględniać czasu w stanie wstrzymania, należy po kawałku zarejestrować dziennik między komunikatami wejścia i wyjścia zawieszenia. Ponadto dzienniki jądra używają strefy czasowej UTC i muszą być dostosowane do strefy czasowej użytkownika.

Identyfikowanie czasu zgłoszenia błędu

Aby określić, kiedy pobrano raport o błędach, najpierw sprawdź dziennik systemowy ( dumpstate: begin :

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

Następnie sprawdź znaczniki czasowe dziennika jądra ( dmesg ) dla komunikatu o uruchomieniu Starting service 'bugreport' :

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

Pracuj wstecz, aby skorelować dwa zdarzenia, pamiętając o zastrzeżeniach wymienionych w sekcji Synchronizowanie osi czasu . Chociaż po zainicjowaniu raportu o błędach dużo się dzieje, większość działań nie jest zbyt użyteczna, ponieważ czynność pobrania raportu o błędach znacznie obciąża system.

Moc

Dziennik zdarzeń zawiera stan zasilania ekranu, gdzie 0 to wyłączony ekran, 1 to ekran włączony, a 2 to blokada klawiatury.

Raporty o błędach zawierają również statystyki dotyczące blokad wybudzania, mechanizmu używanego przez twórców aplikacji do wskazywania, że ​​ich aplikacja musi mieć włączone urządzenie. (Szczegółowe informacje na temat blokad wybudzania znajdują się w PowerManager.WakeLock i Keep the CPU on .)

Zagregowane statystyki czasu trwania blokady wybudzania śledzą tylko czas, w którym blokada wybudzania jest faktycznie odpowiedzialna za utrzymywanie urządzenia w stanie czuwania i nie obejmują czasu, gdy ekran jest włączony. Ponadto, jeśli jednocześnie utrzymywanych jest wiele blokad wybudzania, czas trwania blokady wybudzania jest rozłożony na te blokady wybudzania.

Aby uzyskać dodatkową pomoc w wizualizacji stanu zasilania, użyj Historian baterii , narzędzia Google typu open source do analizowania zużycia baterii przy użyciu plików raportów błędów Androida.

Pakiety

Sekcja DUMP OF SERVICE package zawiera wersje aplikacji (i inne przydatne informacje).

Procesy

Raporty o błędach zawierają ogromną ilość danych dotyczących procesów, w tym czas rozpoczęcia i zakończenia, czas działania, powiązane usługi, wynik oom_adj itp. Szczegółowe informacje na temat zarządzania procesami w systemie Android można znaleźć w sekcji Procesy i wątki .

Określanie czasu trwania procesu

Sekcja procstats zawiera pełne statystyki dotyczące tego, jak długo działają procesy i powiązane usługi. Aby uzyskać szybkie, czytelne dla człowieka podsumowanie, wyszukaj AGGREGATED OVER , aby wyświetlić dane z ostatnich trzech lub 24 godzin, a następnie wyszukaj Summary: aby wyświetlić listę procesów, czas działania tych procesów z różnymi priorytetami oraz ich pamięć RAM użycie sformatowane jako min-średnia-maks. PSS/min-średnia-maks. USS.

Dlaczego proces jest uruchomiony?

Sekcja dumpsys activity processes zawiera listę wszystkich aktualnie uruchomionych procesów uporządkowanych według wyniku oom_adj (Android wskazuje ważność procesu, przypisując procesowi wartość oom_adj , która może być dynamicznie aktualizowana przez ActivityManager). Dane wyjściowe są podobne do migawek pamięci, ale zawierają dodatkowe informacje o tym, co powoduje uruchomienie procesu. W poniższym przykładzie pogrubione wpisy wskazują, że proces gms.persistent działa z priorytetem vis (widocznym), ponieważ proces systemowy jest powiązany z jego NetworkLocationService .

Skany

Wykonaj następujące czynności, aby zidentyfikować aplikacje wykonujące nadmierne skanowanie Bluetooth Low Energy (BLE):

  • Znajdź komunikaty dziennika dla BluetoothLeScanner :
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • Zlokalizuj PID w komunikatach dziennika. W tym przykładzie „24840” i „24851” to PID (identyfikator procesu) i TID (identyfikator wątku).
  • Znajdź aplikację powiązaną z PID:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    

    W tym przykładzie nazwa pakietu to com.badapp .

  • Wyszukaj nazwę pakietu w Google Play, aby zidentyfikować odpowiedzialną aplikację: https://play.google.com/store/apps/details?id=com.badapp .

Uwaga : W przypadku urządzeń z systemem Android 7.0 system zbiera dane do skanowania BLE i kojarzy te działania z aplikacją inicjującą. Aby uzyskać szczegółowe informacje, zobacz Skanowanie o niskim zużyciu energii (LE) i Bluetooth .