Ten przewodnik zawiera omówienie podstawowych narzędzi i technik debugowania usług i aplikacji działających na platformie SDV.
Połącz z urządzeniem
Podstawowym narzędziem do łączenia się z urządzeniem i interakcji z nim jest Android Debug Bridge (adb). Sprawdź, czy adb znajduje się w ścieżce systemowej.
Łączenie się z siecią
Jeśli urządzenie jest w tej samej sieci i znasz jego adres IP, możesz połączyć się przez Ethernet. Nasz system używa wyłącznie połączeń sieciowych do adb:
# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555
Łączenie z wieloma urządzeniami
Aby zarządzać wieloma urządzeniami z jednej stacji roboczej, możesz połączyć się z nimi za pomocą różnych adresów IP. Jeśli na jednym hoście uruchamiasz kilka maszyn wirtualnych, musisz przypisać do każdego urządzenia inne porty. Wymaga to skonfigurowania demona adb na każdym urządzeniu SDV, aby nasłuchiwał na unikalnym porcie, na przykład 5555 w przypadku pierwszego urządzenia i 5556 w przypadku drugiego. Możesz też skonfigurować hosta tak, aby przekierowywał te porty do różnych gości:
# Connect to the first device
adb connect <device_1_ip_address>:5555
# Connect to a second device
adb connect <device_2_ip_address>:5555
# Connect to a second VM on first device on different port
adb connect <device_1_ip_address>:5556
# List all connected devices to verify
adb devices
Podczas uruchamiania kolejnych poleceń adb możesz kierować je na konkretne urządzenie, używając flagi -s z pełnym adresem (ip:port):
# Run a shell command on the second VM on first device in the above example
adb -s <device_1_ip_address>:5556 shell
Wyświetl logi
Jeśli usługa nie działa lub zachowuje się nieoczekiwanie, najpierw sprawdź logi.
Korzystanie z logcat (logi Androida)
logcat wyświetla logi z usług systemowych, agentów i pakietów usług:
# View all logs in real-time
adb logcat
# Filter logs by a specific tag (e.g., the name of your service)
adb logcat -s MyServiceTag
# Filter logs by priority (V: Verbose, D: Debug, I: Info, W: Warn, E: Error, F: Fatal)
# This shows only Error and Fatal messages for a specific tag
adb logcat MyServiceTag:E *:S
# Clear old logs before viewing new ones
adb logcat -c && adb logcat
# Show all logs and return
adb logcat -d
# Color logs by level
adb logcat -v color
# Show timestamps as time since boot
adb logcat -v monotonic
Używanie dmesg (dzienników jądra)
dmesg wyświetla logi z jądra systemu Linux. Jest to kluczowe w przypadku debugowania:
- Problemy ze sprzętem i sterownikami
- Błędy kernel panic
- Odmowy SELinux (
avc: denied) – wyświetlane też w logcat
# View all kernel messages
adb shell dmesg
# Follow kernel messages in real-time
adb shell dmesg -w
Uzyskiwanie dostępu do logów w Cuttlefish
Gdy uruchamiasz aplikację na urządzeniu wirtualnym Cuttlefish, możesz uzyskać bezpośredni dostęp do plików dziennika z systemu plików maszyny hosta. Jest to szczególnie przydatne, gdy usługa adb jest niedostępna. Po uruchomieniu Cuttlefish wyświetla wszystkie ścieżki debugowania. Możesz je też sprawdzić za pomocą polecenia cvd fleet we wszystkich uruchomionych instancjach.
- Logcat (logi Androida):
cuttlefish/instances/cvd-1/logs/logcat - Dzienniki jądra:
cuttlefish/instances/cvd-1/logs/kernel.log - Dzienniki programu uruchamiającego Cuttlefish:
cuttlefish/instances/cvd-1/logs/launcher.log(przydatne do debugowania samego środowiska Cuttlefish)
Aby wyświetlać te pliki w czasie rzeczywistym, możesz użyć standardowych narzędzi wiersza poleceń, takich jak cat, less lub tail -f.
Interakcja z powłoką i systemem plików
Uzyskaj dostęp do powłoki, aby uruchamiać polecenia bezpośrednio na urządzeniu, sprawdzać stan procesu i poruszać się po systemie plików:
# Open an interactive shell on the device
adb shell
# From within the shell, you can check running processes
ps -A
# Or check the status of a specific service managed by init
getprop init.svc.<service_name>
Wykonywanie operacji na systemie plików
Użyj poleceń adb push i adb pull, aby przenosić pliki między komputerem hosta a urządzeniem. Użyj tego, aby wdrożyć skrypty testowe, zaktualizować konfigurację lub pobrać zrzuty awaryjne:
# Push a file from your computer to the device
adb push my_local_file.txt /data/local/tmp/
# Pull a file from the device to your computer
adb pull /data/tombstones/tombstone_00 .
Debugowanie aplikacji (C++/Rust)
Aplikacje możesz debugować online lub offline.
Używanie lldb do debugowania na żywo
Aby debugować usługę w czasie rzeczywistym za pomocą lldb, wykonaj te czynności (aby dołączyć debuger z Android Studio for Platform, zapoznaj się z artykułami Debugowanie i testowanie oraz Debugowanie kodu platformy):
Uruchom ponownie
adbz uprawnieniami roota (wymaganymi do przekierowania portów):adb rootJeśli plik binarny zawiera symbole debugowania, prześlij nieoczyszczoną wersję z
out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]. Aby na przykład przesłać plikrpcagentzsystem_extisdv_core_cf, uruchom:adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmpPołącz się z klientem LLDB za pomocą skryptu
lldbclient.py:# Run and connect a binary on device, run on host: lldbclient.py -r /data/local/tmp/rpcagent # Connect to an existing process with PID 2759 lldbclient.py -p 2759Ten skrypt łączy się zdalnie z
lldb. Aby zobaczyć wszystkie dostępne flagi, uruchom polecenielldbclient.py --help.
Analizowanie zrzutów awaryjnych (nagrobków)
Gdy usługa ulegnie awarii, w /data/tombstones/ zostanie wygenerowany plik tombstone.
Plik zawiera zrzut stosu, mapę pamięci i inne ważne informacje.
Pobierz plik tombstone, a następnie użyj narzędzia rozpoznającego symbole (takiego jak lldb lub specjalny skrypt), aby przeanalizować go za pomocą nieoczyszczonej wersji pliku binarnego.
Przeanalizuj wydajność
SDV obsługuje wiele narzędzi do pomiaru wydajności.
Sprawdzanie wykorzystania procesora i pamięci
top: wyświetla w czasie rzeczywistym listę uruchomionych procesów posortowanych według wykorzystania procesora.adb shell top -m 10 # Show top 10 processesprocrank: zawiera szczegółowe zestawienie wykorzystania pamięci przez konkretny proces lub cały system.adb shell procrank
Używanie dumpsys do sprawdzania stanu usługi
dumpsys to zaawansowane narzędzie do wysyłania zapytań o stan wewnętrzny dowolnej usługi systemowej Androida.
# List all available services
adb shell dumpsys -l
# Dump the state of a specific service or agent
adb shell dumpsys <service_name>
Używanie torq do analizy wydajności
torq to narzędzie wiersza poleceń, które upraszcza zadania profilowania i śledzenia na Androidzie. Umożliwia uruchamianie Simpleperf, Perfetto i innych typowych zadań podczas analizy wydajności systemu.
Używanie Perfetto do śledzenia
Perfetto to standardowe narzędzie do śledzenia całego systemu na Androidzie. Perfetto umożliwia rejestrowanie zdarzeń systemowych, punktów śledzenia na poziomie aplikacji i liczników wydajności oraz wizualizowanie ich na osi czasu.
Najważniejsze kroki:
- Dodaj punkty śledzenia w kodzie C++ lub Rust:
- C++: użyj pakietu Perfetto SDK z makrami
TRACE_EVENT. - Rust: użyj crate
tracing, który emituje zdarzenia ATrace zgodne z Perfetto.
- C++: użyj pakietu Perfetto SDK z makrami
- Utwórz plik konfiguracji textproto, aby określić źródła danych (np.
ftrace,track_event), kategorie i tagi. - Użyj skryptu
record_android_trace(external/perfetto/tools/record_android_trace) z plikiem konfiguracji, aby przechwycić ślad z urządzenia. - Otwórz wygenerowany plik logu czasu w interfejsie internetowym Perfetto, aby przeanalizować zachowanie systemu, zidentyfikować wąskie gardła i zrozumieć interakcje między usługami.
Szczegółowe instrukcje dotyczące instrumentacji, konfiguracji i zbierania danych znajdziesz w artykule Używanie logów czasu do uzyskiwania statystyk dotyczących wydajności systemu.
Używanie Simpleperf do profilowania
Simpleperf to wszechstronne narzędzie wiersza poleceń do profilowania wydajności na Androidzie, podobne do narzędzia perf w systemie Linux.
Częste przypadki użycia:
- Profilowanie procesora: identyfikowanie funkcji, które zużywają najwięcej czasu pracy procesora.
- Analiza poza procesorem: analiza przyczyn uśpienia lub zablokowania wątków.
- Liczniki sprzętowe: dostęp do liczników wydajności sprzętu.
Przykładowe polecenia:
# Go to simpleperf scripts
cd system/extras/simpleperf/scripts
# Profile system for 20 seconds and record call graph
./app_profiler.py --system_wide -r "--call-graph fp --duration 20"
# Record a profile for a specific process (PID 1)
./app_profiler.py --pid 1 -r "--call-graph fp --duration 5"
# Pull the profile data
adb pull /data/local/tmp/perf.data .
# Generate a report with symbol resolution
./report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly -o report.html
Simpleperf oferuje znacznie więcej zdarzeń i opcji. Szczegółowe informacje znajdziesz w przewodniku po Simpleperf.
Odmowy SELinux
Objawy: usługa nie uruchamia się, nie może uzyskać dostępu do pliku lub nie może użyć funkcji, a w dmesg lub logcat pojawia się komunikat avc: denied.
[ 123.456] avc: denied { read } for pid=789 comm="my_service" name="some_file" dev="sda1" ino=123 scontext=u:r:my_service_t:s0 tcontext=u:object_r:some_file_t:s0 tclass=file permissive=0
Szybkie debugowanie (tylko na potrzeby programowania)
Możesz tymczasowo wyłączyć egzekwowanie zasad SELinux, aby sprawdzić, czy problem został rozwiązany. Potwierdza to, że problem jest spowodowany brakiem reguły zasady SELinux.
# Disabling SELinux requires root permission
adb root
# Set SELinux to permissive mode
adb shell setenforce 0
# Check the current mode (should return "Permissive")
adb shell getenforce
Rozwiązanie: użyj narzędzia audit2allow z drzewa źródłowego Androida, aby przeanalizować komunikat o odmowie. Spowoduje to wygenerowanie prawidłowej reguły zasad .te, którą należy dodać do konfiguracji SELinux urządzenia.