Arm linux androideabi gdb

Отладка Android CMake проекта по-взрослому


После перевода наших проектов на CMake, встал вопрос об отладке нативной части Android. Так как инструменты NDK стали неактуальны, пришлось залезть в дебри и научить Eclipse запускать удалённую отладку CDT-проекта, что называется, вручную. В идеале, чтобы это выполнялось в один клик.

Если вам не чужда разработка с использованием Android NDK, и вы хотите познать некоторые тонкости отладки, велкам под кат.

В одной из наших студий было принято решение о переводе кроссплатформенных проектов на CMake, что позволило ускорить их разработку, но также внесло свои коррективы в некоторые этапы. CMake полностью заменил систему сборки ndk-build, и «инструменты отладки» ndk-stack, ndk-gdb стали недоступны. Помедитировав над Eclipse и CDT в частности, появилась мысль о том, что отладку нативного кода CMake Android-проекта можно сделать удобной, быстрой и доступной.

CMake Android-проект

В этой статье мы рассмотрим нашу задачу в слегка уменьшенном масштабе — на примере Teapot из состава Android NDK. Его сборка была переведена с ndk-build скриптов на CMake. Надо пояснить, что CMake не заточен полностью под Android, как и под любую другую платформу. Дополнительный функционал нужно писать самому, что и было сделано в данном случае, поэтому не удивляйтесь, если видите какую-то переменную или функцию, о которых в документации CMake ни слова. Бóльшую часть я попытаюсь описать, но кое-что могу упустить, поэтому если вы решите перенять опыт, то вам придётся вникнуть в используемые скрипты и хотя бы примерно понимать их работу, дабы при выходе новой версии NDK не сесть в лужу.

Для успешной сборки и настройки отладчика, вам понадобятся:

  • Android SDK
  • Android NDK r8+
  • CMake 2.8.11+
  • MinGW (если вы на Windows)
  • Переменная окружения ANDROID_NDK, указывающая на распакованный NDK

После загрузки демо-проекта, запустите cmake.cmd/sh , после чего в Eclipse импортируйте проекты из папок build/android_debug и sources/Teapot .
Для проекта TeapotNativeActivity можно добавить референс на TeapotNativeActivity-Debug@android_debug , чтобы пересборка происходила автоматически.

В итоге у вас должен получиться такой workspace:

Немного теории

Отладка native кода Android-приложения включает в себя несколько этапов:

  1. Сборка нативных библиотек с отладочными символами (чтобы отладчик мог связать код в исходниках и скомпилированный код).
  2. Создание урезанных версий библиотек без отладочных символов, но со ссылкой на них.
  3. Сборка и установка APK на устройство с урезанными версиями библиотек.
  4. Запуск APK.
  5. Поиск идентификатора процесса (PID) запущенного APK.
  6. Запуск удалённого отладчика на устройстве с указанием PID. Отладчик открывает TCP порт на устройстве, куда можно слать команды gdb.
  7. Пробрасывание TCP порта с устройства на локальный компьютер.
  8. Загрузка с устройства системных файлов, необходимых для корректной работы отладчика (установки правильных адресов и смещений).
  9. Запуск отладчика на локальном компьютере с указанием локального TCP порта и конфигурацией путей поиска библиотек и исходников.
Читайте также:  Чем отличается неактивированный windows от активированного

В Eclipse всё это разделяется на несколько основных этапов:

  1. Сборка нативного кода.
  2. Сборка APK.
  3. Запуск APK.
  4. Выполнение скрипта-хелпера для настройки отладчика локально и удалённо.
  5. Запуск отладчика нативного кода.

Наша задача — объединить это всё в один клик.

Challenge accepted

Сборка .so

Сборка отладочных версий библиотек не представляет сложностей (CMake всё делает за нас), однако нюанс поджидает в совместимости форматов отладочной информации. Мы используем для сборки своих проектов arm тулчейн gcc-4.8, в котором почему-то используется gdb, не совместимый из коробки с генерируемым форматом dwarf. Для нахождения общего языка, компилятору нужно указать конкретный формат dwarf.

Для этого прописываем флаги в CMake:

Помещение отладочной информации в отдельный файл

Размер библиотеки с отладочными данными может достигать нескольких сотен мегабайт, что негативно влияет на размер APK и, как следствие, скорость загрузки на устройство. Для решения этой проблемы выполняем strip отладочной информации в отдельный файл:

После сборки, полная версия .so переименовывается в .so.debug , и на её основе создаётся .so с убранной информацией об отладке и ссылкой на .so.debug файл.
Этот код находится в функции set_ndk_gdbserver_compatible(target) в файле CMake/auto_included/android_helpers.cmake . Помимо выполнения стрипа после сборки, он также выполняет другие важные шаги, о которых ниже.

Удаленный отладчик a.k.a. gdbserver

При сборке не отладочной конфигурации файл gdbserver будет удаляться.

Скрипт ndk-gdb.py

Для настройки устройства и локальной машины используется переработанная версия скрипта ndk-gdb.py из Android NDK.

В его задачи входит:

  1. Проверка наличия флага android:debuggable=»true» в AndroidManifest.xml .
  2. Получение идентификатора package из AndroidManifest.xml .
  3. Подключение к девайсу и поиск PID запущенного инстанса по идентификатору package.
  4. Запуск gdbserver , пробрасывание порта.
  5. Копирование дополнительных файлов для отладчика на локальную машину.
  6. Создание файла gdb.setup для отладчика на локальной машине.

Этот скрипт создаётся на основе шаблона CMake/auto_included/stuff/ndk-gdb.py.in в момент вызова set_ndk_gdbserver_compatible(target) . В процессе запуска отладки скрипт должен запускаться после старта APK.

Настройка Eclipse для запуска ndk-gdb.py

Здесь и далее, параллельно описанию, будет идти мануал по настройке демо-проекта.

Добавляем External Tool с такой конфигурацией:

Так как это промежуточный шаг для запуска отладчика, то привязка к билду нам не нужна:

Настройка отладчика C++ Remote Application

Eclipse CDT предлагает несколько вариантов работы отладчика, но нас интересует единственно верный в данном случае: C++ Remote Application .

В настройки отладчика прописываются пути:

  • приложения для отладки
  • отладчика
  • конфигурации отладчика

Приложение для отладки — это файл app_process , который загружается с устройства на локальный компьютер. app_process — это нативный исполняемый файл для платформы Android, через который стартуют все Java-процессы.

Конфигурация отладчика — это файл gdb.setup , в котором указаны пути для поиска библиотек.

После генерации CMake-проекта, в папке build/android_debug/ndk-gdb создаются пустышки app_process и gdb.setup , чтобы на них можно было натравить Eclipse. В момент запуска отладки, скрипт ndk-gdb.py подгружает с девайса настоящий файл app_process и конфигурирует gdb.setup .

Настройка отладчика в Eclipse

Что отлаживаем:

Читайте также:  Компоненты windows что должно быть включено

Чем отлаживаем:

Как удобно-то!

В результате этих действий мы получили несколько разных задач в Eclipse, которые уже позволяют запустить отладку, но для этого нужно:

  1. Запустить APK
  2. Запустить скрипт ndk-gdb.py
  3. Запустить отладчик

Мы же рассчитываем отлаживать наше приложение в один клик, так?

Launch Group to the rescue!

На наше счастье, Eclipse CDT предлагает механизм по автоматизации нескольких разных действий в Eclipse, и имя ему Launch Group.

Создайте конфигурацию с последовательносью:

  1. Запуск отладки APK, задержка 2 секунды. Задержка нужна для стабильного запуска APK, т.к. следующий шаг требует запущенный APK, иначе скрипт не найдёт нужный процесс.
  2. Запуск скрипта ndk-gdb.py, задержка 2 секунды. Задержка нужна для стабильного пробрасывания порта с устройства.
  3. Запуск отладчика C++ Remote Application.

Для удобства на вкладке Common активируйте отображение этого шага на кнопке отладки в Eclipse:

Debug me

Если всё сделано правильно и у вас хорошая карма, то при запуске этого действия вы сможете наслаждаться отладкой вашего проекта:

Что-то пошло не так?

Проблемы бывают, и мы их периодически ловим. Разные девайсы имеют разную производительность, прошивки, версии Android.
Чаще всего сложности возникают из-за медленного запуска APK, что приводит к подключению отладчика ещё на фазе загрузки .so, что негативно сказывается на запуске, и порой вообще невозможно продолжить работу. Для решения этой проблемы нужно увеличить задержку между первым и вторым шагом в Launch Group.
Ещё возможна проблема с зависанием отладчика на девайсе, ребут устройства обычно спасает.

Также в предложенном примере используется ndk-gdb.py скрипт, рассчитанный на то, что его будут запускать только на Linux x86, Mac OS X x64 или Windows x64. Если ваша конфигурация отличается, то вам придётся его подкрутить.

Заключение

Всё это позволило значительно упростить отладку любого Android CMake-проекта, и мы этому несказанно рады. Конечно, есть простор для улучшений и оптимизаций: в идеале хочется сделать нечто, что могло бы настроить все эти шаги в Eclipse автоматически, потому как каждый новый проект/ветка требует такой настройки.

Если у вас появились вопросы или предложения по улучшению/упрощению схемы, я буду рад их услышать!

Источник

Arm linux androideabi gdb

Xamarin.Android 4.10 introduced partial support for using gdb by using the _Gdb MSBuild target.

gdb support requires that the Android NDK be installed.

There are three ways to use gdb :

When things go wrong, please see the Troubleshooting section.

Debug Builds with Fast Deployment

When building and deploying a Debug build with Fast Deployment enabled, gdb can be attached by using the _Gdb MSBuild target.

First, install the app. This can be done via the IDE, or via the command line:

Secondly, run the _Gdb target. At the end of execution, a gdb command line will be printed:

The _Gdb target will launch an arbitrary launcher Activity declared within your AndroidManifest.xml file. To explicitly specify which Activity to run, use the RunActivity MSBuild property. Starting Services and other Android constructs is not supported at this time.

The _Gdb target will create a gdb-symbols directory and copy the contents of your target’s /system/lib and $APPDIR/lib directories there.

Читайте также:  Полные библиотеки dll для windows

The contents of the gdb-symbols directory are tied to the Android target you deployed to, and will not be automatically replaced should you change the target. (Consider this a bug.) If you change Android target devices, you will need to manually delete this directory.

Finally, copy the generated gdb command and execute it in your shell:

Debug Builds without Fast Deployment

Debug builds with Fast Deployment operate by copying the Android NDK’s gdbserver program into the Fast Deployment .__override__ directory. When Fast Deployment is disabled, this directory may not exist.

There are two workarounds:

  • Set the debug.mono.log system property so that the .__override__ directory is created.
  • Include gdbserver within your .apk .

Setting the debug.mono.log System Property

To set the debug.mono.log system property, use the adb command:

Once the system property has been set, execute the _Gdb target and the printed gdb command, as with the Debug Builds with Fast Deployment configuration:

Including gdbserver in your app

To include gdbserver within your app:

Find gdbserver within your Android NDK (it should be in $ANDROID_NDK_PATH/prebuilt/android-arm/gdbserver/gdbserver), and copy it into your Project directory.

Rename gdbserver to libs/armeabi-v7a/libgdbserver.so.

Add libs/armeabi-v7a/libgdbserver.so to your Project with a Build action of AndroidNativeLibrary .

Rebuild and reinstall your application.

Once the app has been reinstalled, execute the _Gdb target and the printed gdb command, as with the Debug Builds with Fast Deployment configuration:

Release Builds

gdb support requires three things:

  1. The INTERNET permission.
  2. App Debugging enabled.
  3. An accessible gdbserver .

The INTERNET permission is enabled by default in Debug apps. If it is not already present in your application, you may add it either by editing Properties/AndroidManifest.xml or by editing the Project Properties.

App debugging can be enabled by either setting the ApplicationAttribute.Debugging custom attribute property to true , or by editing Properties/AndroidManifest.xml and setting the //application/@android:debuggable attribute to true :

An accessible gdbserver may be provided by following the Debug Builds without Fast Deployment section.

One wrinkle: The _Gdb MSBuild target will kill any previously running app instances. This will not work on pre-Android v4.0 targets.

Troubleshooting

mono_pmip doesn’t work

The mono_pmip function (useful for obtaining managed stack frames) is exported from libmonosgen-2.0.so , which the _Gdb target does not currently pull down. (This will be fixed in a future release.)

To enable calling functions located in libmonosgen-2.0.so , copy it from the target device into the gdb-symbols directory:

Then restart your debugging session.

Bus error: 10 when running the gdb command

When the gdb command errors out with «Bus error: 10» , restart the Android device.

No stack trace after attach

This is usually a sign that the contents of the gdb-symbols directory are not synchronized with your Android target. (Did you change your Android target?)

Please delete the gdb-symbols directory and try again.

Источник

Оцените статью