Ndk-Gdb

Pakiet NDK zawiera skrypt powłoki o nazwie ndk-gdb, który uruchamia sesję debugowania wbudowanego w wierszu poleceń. Użytkownicy, którzy wolą korzystać z GUI, powinni zapoznać się z dokumentacją dotyczącą debugowania w Android Studio.

Wymagania

Aby debugowanie natywne wiersza poleceń działało, muszą być spełnione te wymagania:

  • Utwórz aplikację, korzystając ze skryptu ndk-build. Skrypt ndk-gdb nie obsługuje tworzenia starszej metody make APP=<name>.
  • Włącz debugowanie aplikacji w pliku AndroidManifest.xml, dodając element <application>, który ustawia wartość atrybutu android:debuggable na true.
  • Stwórz aplikację tak, aby działała na Androidzie 2.2 (interfejs API Androida na poziomie 8) lub nowszym.
  • Debuguj na urządzeniu lub w emulatorze z Androidem 2.2 lub nowszym. Do celów debugowania docelowy poziom interfejsu API deklarowany w pliku AndroidManifest.xml nie ma znaczenia.
  • Programuj aplikację w powłoce uniksowej. W systemie Windows użyj Cygwina lub eksperymentalnego wdrożenia ndk-gdb-py Python.
  • Użyj programu GNU Make 3.81 lub nowszego.

Wykorzystanie

Aby wywołać skrypt ndk-gdb, przejdź do katalogu aplikacji lub dowolnego katalogu znajdującego się pod nim. Na przykład:

cd $PROJECT
$NDK/ndk-gdb

$PROJECT wskazuje tutaj katalog główny projektu, a $NDK – ścieżkę instalacji NDK.

Wywołanie ndk-gdb konfiguruje sesję pod kątem wyszukiwania plików źródłowych i wersji symboli/debugowania wygenerowanych bibliotek natywnych. Po pomyślnym dołączeniu do procesu aplikacji ndk-gdb generuje długą serię komunikatów o błędach z informacją, że nie może znaleźć różnych bibliotek systemowych. Jest to normalne, ponieważ Twój host nie zawiera wersji symboli/debugowania tych bibliotek na urządzeniu docelowym. Możesz je bez obaw zignorować.

Następnie ndk-gdb wyświetla normalny prompt dla GDB.

Z narzędzia ndk-gdb korzystasz w taki sam sposób jak z GNU GDB. Możesz na przykład użyć b <location>, aby ustawić punkty przerwania, i c (aby wznowić wykonanie). Pełną listę poleceń znajdziesz w instrukcji GDB. Jeśli wolisz korzystać z Debugera LLDB, użyj opcji --lldb podczas wywoływania skryptu ndk-gdb.

Pamiętaj, że po zamknięciu promptu GDB proces aplikacji, który debugujesz, zostanie zatrzymany. Jest to ograniczenie gdb.

ndk-gdb obsługuje wiele warunków błędów i wyświetla informacyjny komunikat o błędzie, jeśli znajdzie problem. W ramach tych testów sprawdza się, czy zostały spełnione te warunki:

  • Sprawdza, czy na ścieżce znajduje się ADB.
  • Sprawdza, czy w pliku manifestu aplikacji można debugować.
  • Sprawdza, czy na urządzeniu można debugować również zainstalowaną aplikację o tej samej nazwie pakietu.

Domyślnie ndk-gdb wyszukuje już uruchomiony proces aplikacji, a jeśli go nie znajdzie, wyświetla błąd. Możesz jednak użyć opcji --start lub --launch=<name>, aby automatycznie rozpoczynać aktywność przed sesją debugowania. Więcej informacji znajdziesz w sekcji Opcje.

Opcje

Aby zobaczyć pełną listę opcji, wpisz ndk-gdb --help w wierszu poleceń. W tabeli 1 znajdziesz te najczęściej używane wraz z krótkimi opisami.

Tabela 1. Typowe opcje ndk-gdb i ich opisy.

Uruchomienie ndk-gdb z tą opcją powoduje uruchomienie pierwszego działania, które można uruchomić, wymienione w pliku manifestu aplikacji. Użyj --launch=<name>, aby uruchomić następne działanie, które można uruchomić. Aby skopiować listę działań możliwych do uruchomienia, uruchom polecenie --launch-list z wiersza poleceń.

Opcja Opis>
--lldb

Jeśli zasada jest skonfigurowana, skrypt na potrzeby sesji będzie używał debugera LLDB, a nie gdb.

--verbose

Ta opcja informuje system kompilacji o tym, że ma wydrukować szczegółowe informacje o konfiguracji sesji debugowania natywnego. Jest ona potrzebna tylko do debugowania problemów, gdy debuger nie może połączyć się z aplikacją, a komunikaty o błędach wyświetlane przez ndk-gdb nie są wystarczające.

--force Domyślnie ndk-gdb przerywa działanie, jeśli wykryje, że inna sesja debugowania natywnego jest już uruchomiona na tym samym urządzeniu. Ta opcja zamyka inną sesję i zastępuje ją nową. Pamiętaj, że ta opcja nie powoduje zakończenia debugowania aktualnie debugowanej aplikacji, którą należy zamknąć oddzielnie.
--start

Po uruchomieniu ndk-gdb próbuje domyślnie połączyć się z istniejącą uruchomioną instancją aplikacji na urządzeniu docelowym. Możesz zastąpić to domyślne działanie, używając polecenia --start do wyraźnego uruchomienia aplikacji na urządzeniu docelowym przed sesją debugowania.

--launch=<name>

Ta opcja jest podobna do --start z tą różnicą, że pozwala uruchomić określoną aktywność w aplikacji. Ta funkcja jest przydatna tylko wtedy, gdy plik manifestu zawiera wiele działań, które można uruchomić.

--launch-list

Ta wygodna opcja powoduje wydrukowanie listy wszystkich możliwych do uruchomienia nazw działań, które znajdują się w pliku manifestu aplikacji. --start używa pierwszej nazwy aktywności.

--project=<path> Ta opcja określa katalog projektu aplikacji. Jest to przydatne, jeśli chcesz uruchomić skrypt bez konieczności przechodzenia do katalogu projektu.
--port=<port>

Domyślnie ndk-gdb używa lokalnego portu TCP 5039 do komunikacji z aplikacją, którą debuguje na urządzeniu docelowym. Użycie innego portu umożliwia natywne debugowanie programów działających na różnych urządzeniach lub emulatorów podłączonych do tego samego hosta.

--adb=<file>

Ta opcja określa plik wykonywalny narzędzia adb. Jest to konieczne tylko wtedy, gdy nie masz ustawionej ścieżki uwzględniającej ten plik wykonywalny.

  • -d
  • -e
  • -s <serial>
  • Flagi te są podobne do poleceń adb o tych samych nazwach. Ustaw te flagi, jeśli z hostem jest podłączonych kilka urządzeń lub emulatorów. Ich znaczenie jest następujące:

    -d
    Połącz urządzenie z jednym urządzeniem fizycznym.
    -e
    Połącz urządzenie z jednym emulatorem.
    -s <serial>
    Połącz się z konkretnym urządzeniem lub emulatorem. <serial> to nazwa urządzenia podana w poleceniu adb devices.

    Możesz też zdefiniować zmienną środowiskową ADB_SERIAL, aby wyświetlić konkretne urządzenie bez konieczności podawania konkretnej opcji.

  • --exec=<file>
  • -x <file>
  • Ta opcja powoduje, że ndk-gdb uruchamia polecenia inicjowania GDB z <file> po nawiązaniu połączenia z procesem, który jest debugowany. Jest to przydatna funkcja, gdy chcesz robić coś wielokrotnie, na przykład ustawić listę punktów przerwania, a potem automatycznie wznawiać wykonywanie.

    --nowait

    Wyłącz wstrzymywanie kodu Java do czasu połączenia z GDB. Po przekroczeniu tej opcji debuger może pomijać wczesnych punktów przerwania.

    --tui -t

    Włącz interfejs tekstowy, jeśli jest dostępny.

    --gnumake-flag=<flag>

    Ta opcja to dodatkowa flaga (lub flagi), która należy przekazać do systemu ndk-build, gdy wysyła do niego zapytanie o informacje o projekcie. Tej opcji można użyć w wielu instancjach w jednym poleceniu.

    Uwaga: 3 ostatnie opcje w tej tabeli dotyczą tylko ndk-gdb w języku Python.

    Obsługa wątków

    Jeśli Twoja aplikacja działa na platformie starszej niż Android 2.3 (poziom interfejsu API 9), ndk-gdb nie może prawidłowo debugować wątków natywnych. Debuger może debugować tylko wątek główny, a abd całkowicie ignoruje wykonanie innych wątków.

    Jeśli umieścisz punkt przerwania w funkcji wykonywanej w wątku innym niż główny, program zostanie zamknięty, a GDB wyświetli następujący komunikat:

    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
          The program no longer exists.