debugging-native-code.md 11 KB


title: Отладка нативного кода в Defold

brief: Это руководство объясняет как отлаживать нативный код в Defold.

Отладка нативного кода

Defold неплохо протестирован и очень редко дает сбой при нормальных обстоятельствах. Однако невозможно гарантировать, что он никогда не выйдет из строя, особенно если ваша игра использует нативные расширения. Если вы столкнетесь с проблемами, связанными со сбоями или собственным кодом, который ведет себя не так, как ожидалось, есть несколько способов продвинуться с проблемой:

  • Используйте отладчик для пошагового выполнения кода
  • Используйте отладочный вывод
  • Анализируйте логи сбоев
  • Сгенерируйте отладочные символы к стеку вызовов

Использование отладчика

Самый распространенный способ - запустить код через отладчик. Он позволяет вам пройти по коду, установить точки останова (breakpoints) и он остановит выполнение, если вы получите сбой.

Для каждой платформы существует несколько отладчиков.

  • Visual studio - Windows
  • VSCode - Windows, macOS, Linux
  • Android Studio - Windows, macOS, Linux
  • Xcode - macOS
  • WinDBG - Windows
  • lldb / gdb - macOS, Linux, (Windows)
  • ios-deploy - macOS

Каждый инструмент может отлаживать определенные платформы:

  • Visual studio - Windows + платформы с поддержкой gdbserver (например, Linux/Android)
  • VSCode - Windows, macOS (lldb), Linux (lldb/gdb) + платформы с поддержкой gdbserve
  • Xcode - macOS, iOS (узнать больше)
  • Android Studio - Android (узнать больше)
  • WinDBG - Windows
  • lldb/gdb - macOS, Linux, (iOS)
  • ios-deploy - iOS (via lldb)

Применение отладочного вывода

Самый простой способ отладки нативного кода - использовать отладочную печать. Используйте функции в пространстве имен dmLog, чтобы наблюдать за переменными или обозначать поток выполнения. Использование любой из функций логирования приведет к печати в секции Console в редакторе и в лог игры.

Анализ лога сбоя

Движок Defold сохраняет файл _crash в случае серьезного сбоя. crash файл будет содержать информацию о системе, а также о сбое. В выводе лога игры будет записано, где находится crash файл (это зависит от операционной системы, устройства и приложения).

Вы можете использовать crash модуль, чтобы прочитать этот файл в следующей сессии. Рекомендуется прочитать файл, собрать информацию, вывести ее в консоли и отправить в сервисы аналитики, которые поддерживают сбор crash логов.

::: important В Windows также создается файл _crash.dmp. Этот файл полезен при отладке сбоя. :::

Получение лога сбоев с устройства

Если сбой происходит на мобильном устройстве, вы можете загрузить crash файл на свой компьютер и проанализировать его локально.

Android

Если приложение в режиме отладки, вы можете получить лог сбоев с помощью Android Debug Bridge (ADB) tool и команды adb shell:

	$ adb shell "run-as com.defold.example sh -c 'cat /data/data/com.defold.example/files/_crash'" > ./_crash

iOS

В iTunes вы можете просмотреть/загрузить контейнер приложений.

В окне Xcode -> Devices вы также можете выбрать логи сбоев.

Генерация отладочных символов к стеку вызовов

Если вы получили стек вызовов либо из файла _crash, либо из лог файла, вы можете сгенерировать отладочные символы. Это означает перевод каждого адреса в стеке вызовов в имя файла и номер строки, что, в свою очередь, помогает при обнаружении основной причины падения.

Очень важно, чтобы вы сопоставили правильный движок со стеком вызовов. В противном случае очень вероятно, что вы получите неверную отладку. Если вы работаете с нативными расширениями, не забудьте добавить флаг --with-symbols к утилите bob или установите флажок "Generate debug symbols" в диалоговом окне пакета в редакторе, чтобы получить все необходимые данные с сервера сборки:

  • iOS — папка dmengine.dSYM.zip в build/arm64-ios содержит символы отладки для сборок iOS.
  • macOS — папка dmengine.dSYM.zip в build/x86_64-macos содержит символы отладки для сборок macOS.
  • Android — папка projecttitle.apk.symbols/lib/ в выходном архиве сборки содержит символы отладки для целевых архитектур.
  • Linux — исполняемый файл содержит символы отладки.
  • Windows — файл dmengine.pdb в build/x86_64-win32 содержит символы отладки для сборок Windows.
  • HTML5 — файл dmengine.js.symbols в build/js-web или build/wasm-web содержит символы отладки для сборок HTML5.

::: important Очень важно, чтобы вы сохранили где-нибудь символы отладки для каждого публичного релиза вашей игры, и чтобы вы знали, к какому релизу принадлежат отладочные символы. Вы не сможете отлаживать нативные сбои, если у вас не будет отладочных символов! Кроме того, вы должны держать под рукой включающую отладочные символы версию движка. Это позволяет лучше всего отображать стек вызовов. :::

Загрузка символов отладки в Google Play

Вы можете загрузить символы отладки в Google Play, чтобы все сбои, зарегистрированные в Google Play, отображались с расшифрованными стеками вызовов. Заархивируйте содержимое папки projecttitle.apk.symbols/lib/ из выходного архива сборки. Эта папка содержит одну или несколько подпапок с названиями архитектур, например arm64-v8a и armeabi-v7a.

Генерация отладочных символов к стеку вызовов Android

  1. Получите его из папки сборки

    	$ ls <project>/build/<platform>/[lib]dmengine[.exe|.so]
    
  2. Распакуйте архив:

    	$ unzip dmengine.apk -d dmengine_1_2_105
    
  3. Найдите адрес в стеке вызовов

    Например, в стеке вызовов без отладочных символов это могло бы выглядеть так

    #00 pc 00257224 libmy_game_name.so

    Где 00257224 это адрес

  4. Обработайте этот адрес командой

    $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_
    

Примечание: Если вы получите стектрейс из логов Android, вы можете снабдить его отладочными символами с помощью ndk-stack.

Генерация отладочных символов к стеку вызовов iOS

  1. Если вы используете нативные расширения, сервер может предоставить вам символы (.dSYM) (передайте ключ --with-symbols в bob.jar)

    	$ unzip <project>/build/arm64-darwin/build.zip
    	# it will produce a Contents/Resources/DWARF/dmengine
    
  2. Если вы не используете нативные расширения, скачайте стандартные отладочные символы:

    	$ wget http://d.defold.com/archive/<sha1>/engine/arm64-darwin/dmengine.dSYM
    
  3. Получите отладочные символы, используя адрес загрузки

    По какой-то причине простое добавление адреса из стека вызовов не работает (т. е. адрес загрузки 0x0)

    		$ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4
    

    Также никакого результата не даст задание адреса загрузки напрямую

    		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4
    

    Добавление адреса загрузки к адресу из стека вызовов даст нужный результат:

    		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4
    		dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27)