--- 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 ([узнать больше](/manuals/debugging-native-code-ios)) * Android Studio - Android ([узнать больше](/manuals/debugging-native-code-android)) * WinDBG - Windows * lldb/gdb - macOS, Linux, (iOS) * ios-deploy - iOS (via lldb) ## Применение отладочного вывода Самый простой способ отладки нативного кода - использовать [отладочную печать](http://en.wikipedia.org/wiki/Debugging#Techniques). Используйте функции в [пространстве имен dmLog](/ref/stable/dmLog/), чтобы наблюдать за переменными или обозначать поток выполнения. Использование любой из функций логирования приведет к печати в секции *Console* в редакторе и в [лог игры](/manuals/debugging-game-and-system-logs). ## Анализ лога сбоя Движок Defold сохраняет файл `_crash` в случае серьезного сбоя. crash файл будет содержать информацию о системе, а также о сбое. В [выводе лога игры](/manuals/debugging-game-and-system-logs) будет записано, где находится crash файл (это зависит от операционной системы, устройства и приложения). Вы можете использовать [crash модуль](https://www.defold.com/ref/crash/), чтобы прочитать этот файл в следующей сессии. Рекомендуется прочитать файл, собрать информацию, вывести ее в консоли и отправить в [сервисы аналитики](/tags/stars/analytics/), которые поддерживают сбор crash логов. ::: important В Windows также создается файл `_crash.dmp`. Этот файл полезен при отладке сбоя. ::: ### Получение лога сбоев с устройства Если сбой происходит на мобильном устройстве, вы можете загрузить crash файл на свой компьютер и проанализировать его локально. #### Android Если приложение [в режиме отладки](/manuals/project-settings/#android), вы можете получить лог сбоев с помощью [Android Debug Bridge (ADB) tool](https://developer.android.com/studio/command-line/adb.html) и команды `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`, либо из [лог файла](/manuals/debugging-game-and-system-logs), вы можете сгенерировать отладочные символы. Это означает перевод каждого адреса в стеке вызовов в имя файла и номер строки, что, в свою очередь, помогает при обнаружении основной причины падения. Очень важно, чтобы вы сопоставили правильный движок со стеком вызовов. В противном случае очень вероятно, что вы получите неверную отладку. Если вы работаете с нативными расширениями, не забудьте добавить флаг [--with-symbols](https://www.defold.com/manuals/bob/) к [утилите bob](https://www.defold.com/manuals/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](https://developer.android.com/studio/build/shrink-code#android_gradle_plugin_version_40_or_earlier_and_other_build_systems), чтобы все сбои, зарегистрированные в Google Play, отображались с расшифрованными стеками вызовов. Заархивируйте содержимое папки `projecttitle.apk.symbols/lib/` из выходного архива сборки. Эта папка содержит одну или несколько подпапок с названиями архитектур, например `arm64-v8a` и `armeabi-v7a`. ### Генерация отладочных символов к стеку вызовов Android 1. Получите его из папки сборки ```sh $ ls /build//[lib]dmengine[.exe|.so] ``` 2. Распакуйте архив: ```sh $ unzip dmengine.apk -d dmengine_1_2_105 ``` 3. Найдите адрес в стеке вызовов Например, в стеке вызовов без отладочных символов это могло бы выглядеть так `#00 pc 00257224 libmy_game_name.so` Где *00257224* это адрес 4. Обработайте этот адрес командой ```sh $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_ ``` Примечание: Если вы получите стектрейс из [логов Android](/manuals/debugging-game-and-system-logs), вы можете снабдить его отладочными символами с помощью [ndk-stack](https://developer.android.com/ndk/guides/ndk-stack.html). ### Генерация отладочных символов к стеку вызовов iOS 1. Если вы используете нативные расширения, сервер может предоставить вам символы (.dSYM) (передайте ключ `--with-symbols` в bob.jar) ```sh $ unzip /build/arm64-darwin/build.zip # it will produce a Contents/Resources/DWARF/dmengine ``` 2. Если вы не используете нативные расширения, скачайте стандартные отладочные символы: ```sh $ wget http://d.defold.com/archive//engine/arm64-darwin/dmengine.dSYM ``` 3. Получите отладочные символы, используя адрес загрузки По какой-то причине простое добавление адреса из стека вызовов не работает (т. е. адрес загрузки 0x0) ```sh $ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4 ``` # Также никакого результата не даст задание адреса загрузки напрямую ```sh $ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4 ``` Добавление адреса загрузки к адресу из стека вызовов даст нужный результат: ```sh $ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4 dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27) ```