Korzystanie z debugerów

Ta strona zawiera informacje o używaniu LLDB do tworzenia systemu operacyjnego. Jeśli chcesz tworzyć aplikacje, skorzystaj z artykułu Debugowanie aplikacji, który zawiera informacje o używaniu interfejsu graficznego Android Studio (opartego na LLDB).

GDB nie jest już obsługiwany ani udostępniany. Jeśli przechodzisz z GDBa na LLDB, najpierw przeczytaj samouczek LLDB. Jeśli jesteś doświadczonym użytkownikiem GDB, mapa poleceń GDB na LLDB może być bardzo przydatna podczas przejścia.

Wymagania wstępne

Aby użyć debugera:

  • Skonfiguruj środowisko kompilacji za pomocą zwykłego polecenia envsetup.sh.
  • Uruchom to samo polecenie lunch, które zostało użyte podczas kompilowania. Pamiętaj, że lunch powinien odpowiadać urządzeniu, które debugujesz. Jeśli element lunch nie pasuje do podłączonego urządzenia, pojawi się błąd w takim formacie: You used the wrong lunch: TARGET_PRODUCT (aosp_arm64) does not match attached device (xyzabc)
  • Podłącz urządzenie do maszyny.

Więcej informacji o konfigurowaniu środowiska znajdziesz w artykule Konfigurowanie środowiska.

Debugowanie pliku binarnego

Aby debugować plik binarny utworzony na komputerze, musisz najpierw skopiować go na urządzenie, a potem uruchomić debuger. Przykład:

adb push test.exe /data/local/tmp/test.exe
lldbclient.py --port 5038 -r /data/local/tmp/test.exe

debugowanie uruchomionych aplikacji lub procesów;

Aby połączyć się z uruchomioną aplikacją lub natywnym demonem, użyj opcji lldbclient.py z identyfikatorem PID. Aby na przykład debugować proces o identyfikatorze PID 1234, wykonaj na hoście to polecenie:

lldbclient.py -p 1234

Skrypt konfiguruje przekierowanie portów, uruchamia odpowiedni moduł debugowania zdalnego na urządzeniu, uruchamia debuger na hoście, konfiguruje go tak, aby znajdował symbole, i łączy go z modułem debugowania zdalnego.

Debugowanie uruchamiania procesu natywnego

Aby debugować proces podczas jego uruchamiania, użyj lldbclient.py z opcją -r. Aby na przykład debugować ls /bin, uruchom na hoście to polecenie:

lldbclient.py -r /system/bin/ls /bin

Następnie wpisz continue, gdy pojawi się odpowiedni komunikat w debugerze.

Debugowanie uruchamiania aplikacji

Czasami chcesz debugować aplikację podczas jej uruchamiania, np. gdy wystąpił błąd i chcesz sprawdzić kod, aby zobaczyć, co stało się przed awarią. Dołączanie w niektórych przypadkach działa, ale w innych jest niemożliwe, ponieważ aplikacja ulega awarii, zanim uda Ci się coś dołączyć. Podejście logwrapper (używane w przypadku strace) nie zawsze działa, ponieważ aplikacja może nie mieć uprawnień do otwierania portu, a lldbserver dziedziczy tę ograniczenie.

Aby debugować uruchamianie aplikacji, użyj opcji programisty w Ustawieniach, aby wskazać aplikacji, że ma czekać na połączenie z debugerem Javy:

  1. Kliknij Ustawienia > Opcje programisty > Wybierz aplikację do debugowania i wybierz aplikację z listy, a potem kliknij Czekaj na debuger.
  2. Uruchom aplikację z poziomu programu uruchamiającego lub za pomocą wiersza poleceń:
    adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
    
  3. Poczekaj, aż aplikacja się załaduje i pojawi się okno z informacją, że czeka ona na debuger.
  4. Dołącz lldbserver/lldbclient w zwykły sposób, ustaw punkty kontrolne, a potem kontynuuj proces.

Aby uruchomić aplikację, dołącz debugger Java Debug Wire Protocol (JDWP), np. Java Debugger (jdb):

adb forward tcp:12345 jdwp:XXX  # (Where XXX is the PID
of the debugged process.)
jdb -attach localhost:12345

debugowanie aplikacji lub procesów, które ulegają awarii;

Jeśli chcesz, aby debuggerd zawieszał procesy, które uległy awarii, aby umożliwić Ci dołączenie debugera, ustaw odpowiednią właściwość:

  • Po Androidzie 11
    adb shell setprop debug.debuggerd.wait_for_debugger true
    
  • Android 11 i starsze
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow i starsze
    adb shell setprop debug.db.uid 999999
    

Na końcu zwykłego wyjścia z błędem debuggerd znajdziesz instrukcje kopiowania i wklejania w logcat, które pokazują, jak połączyć debuger z uszkodzonym procesem.

Debugowanie w VS Code

LLDB obsługuje debugowanie kodu platformy w Visual Studio Code. Aby kontrolować i debugować kod natywny działający na urządzeniach, możesz użyć interfejsu debugera VS Code zamiast interfejsu wiersza poleceń LLDB.

Zanim użyjesz VS Code do debugowania, zainstaluj rozszerzenie CodeLLDB.

Aby debugować kod za pomocą VS Code:

  1. Upewnij się, że są obecne wszystkie artefakty kompilacji (np. symbole) wymagane do wykonania lldbclient.py lub lldbclient.py.
  2. W VS Code naciśnij Ctrl+Shift+P, aby uruchomić polecenie, wyszukaj Debug: Add Configuration..., a następnie wybierz LLDB. Otworzy to plik launch.json i doda nowy obiekt JSON do listy.
  3. Zastąp nowo dodaną konfigurację debugera 2 wierszami komentarza (// #lldbclient-generated-begin// #lldbclient-generated-end), aby lista konfiguracji wyglądała tak:
    "configurations": [
        // #lldbclient-generated-begin
        // #lldbclient-generated-end
    ]

    lldbclient.py używa tych komentarzy do wykrywania miejsca zapisu konfiguracji. Jeśli na liście są inne elementy, dodaj wiersze komentarzy na końcu, po innych konfiguracjach.

  4. W terminalu, w którym uruchomiono envsetup.shlunch, uruchom to polecenie:
    lldbclient.py --setup-forwarding vscode-lldb \
          --vscode-launch-file LAUNCH_JSON_PATH \
          ANY_OTHER_FLAGS -p pid | -n proc-name | -r ...

    lldbclient.py zapisuje wygenerowaną konfigurację w launch.json i nadal działa. To normalne. Nie zabijaj programu lldbclient.py. Jeśli pominiesz element --vscode-launch-file, skrypt wypisze fragment kodu JSON, który musisz skopiować i wkleić ręcznie do elementu launch.json.

    Flaga -r musi być ostatnią flagą, jeśli występuje, ze względu na sposób analizowania flag przez narzędzie.

  5. Otwórz panel boczny Uruchom i debuguj – nowa konfiguracja powinna pojawić się na liście debugera. Naciśnij Rozpocznij debugowanie (F5). Debuger powinien połączyć się po 10–30 sekundach.

    Jeśli nowa konfiguracja nie pojawiła się w widoku Uruchom i Debuguj, ponownie załaduj okno, aby odświeżyć listę debugera. Naciśnij Ctrl + Shift + P i wpisz reload window.

  6. Po zakończeniu debugowania otwórz terminal działający w ramachlldbclient.py i naciśnij Enter, aby zakończyćlldbclient.py program. Kolejne uruchomienia skryptu będą generować konfigurację między komentarzami #lldbclient-generated i zastępować stare treści, więc nie musisz ich usuwać ręcznie.

Aby dodać właściwości niestandardowe do wygenerowanej konfiguracji uruchamiania, możesz użyć flagi --vscode-launch-props. Przykład:

lldbclient.py --setup-forwarding vscode-lldb \
    --vscode-launch-props \
    '{"initCommands" : ["script print(\"Hello\")"], "preLaunchTask" : "Build"}' \
    ...
Te przykładowe właściwości sprawią, że VS Code uruchomi zadanie o nazwie Build przed debugowaniem i doda nowy krok inicjalizowania debugowania do kroków wygenerowanych przez skrypt. Omówienie dostępnych właściwości znajdziesz w dokumentacji VS Code i w podręczniku użytkownika rozszerzenia CodeLLDB.