Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

отладка зависающего приложения VS

#c_sharp #unity3d #отладка


В Unity зависает редактор. Если сбилдить программу(под вин), то она тоже зависает(no
responding). Не могу найти причину: выполняю неопределенное количество раз одно и тоже
действие и потом зависание. Поставить breakpoint не могу потому, что не ясно где их
ставить. Мне кажется, что зависает где-то  в скриптах юнити. 

Как можно получить место в котором программа зависает? Можно ли посмотреть какой
то журнал где выписаны все действия программы? Я думаю что где-то получается бесконечный
цикл, хотя я все циклы проверил...

Спасибо!
    


Ответы

Ответ 1



Есть минимум три решения (если есть другие — дайте знать): два быстрых и одно долгое. Причем долгое связанно именно с Visual Studio (почему у Microsoft не может быть всё просто?) Наибыстрейшее (но материально затратное) Нужно пойти в UnityAssetStore и найти ассет (asset) под названием Panic Button. Он находится в разделе Editor Extensions/System. На данный момент этот ассет находится вот здесь. Что он делает? Когда приложение крутится в бесконечном цикле и интерфейс Unity висит, достаточно нажать клавиши Shift + Esc и происходит "обрыв" главного потока, интерфейс отвисает. При этом проигрывание ставится на паузу, а в консоли отображается проблемное место: Как конкретно она работает? Что происходит внутри? Скорее всего то, что будет описано в пункте №3, только сделанное в виде скрипта, упакованного в dll (чтоб никто не видел код 😆), подключаемую к проекту. Использовать MonoDevelop     Шаги следующие: Пишем скрипт с бесконечным циклом, вешаем на объект и нажимаем Play :-) Идем в MonoDevelop и нажимаем Run → Attach To Process В появившемся окне выбираем Unity и нажимаем Attach Нажимаем кнопку Pause в MonoDevelop Mono уже остановится в проблемном месте и высветится StackTrace Остается теперь поставить Breakpoint на строку, изменить значение, которое вводит в бесконечный цикл (в данном случае присвоить i значение 20, например) и нажать Continue Execution Вздохнуть с облегчением. Использовать Visual Studio     Шаги: Пишем скрипт с бесконечным циклом, вешаем на объект и нажимаем Play :-) Например скрипт такой: using UnityEngine; public class Quicksand : MonoBehaviour { void OnMouseDown() { while(true) { // "Mind you, you'll keep sinking forever!!", -- My mom } } } Идем в Visual Studio, нажимаем в меню Debug → Attach to Process и выбираем в списке процессов Unity. Заметка (!): Именно Attach to Process, а НЕ Attach To Unity Далее нажимаем Debug → Break all, чтоб остановить процесс Нужно найти дизассемблированный вид (если он автоматически не появился). В теории на вкладке StackTrace если нажать два раза ЛКМ, то появится окно, в котором можно нажать ссылку view disassembly И через стэк попасть в место зависания. Анимация ниже должна полностью показать, как пробраться туда: В итоге получаем примерно следующую картину: Из него практически видно бесконечный цикл. В реальности код может быть сложнее и будет трудно быстро разобрать, что там происходит, но сильно можно не вникать, ибо есть небольшой трюк (см. следующий шаг): F10 - сделать шаг в отладке, не заходя в функцию/метод. Соответственно, теперь пошагово нажимаем F10, пока не перелетим со строки 000000001015A758 jmp 000000001015A743 на строку с инструкцией cmp dword ptr [r11], 0. В итоге во вкладке Autos в Visual Studio должны появится данные значения: Теперь просто меняем значение "переменной" R11 на ноль (0) Так как мы стоим на адресе cmp, то при попытки исполнить инструкцию, она попытается прочитать address 0, что, в свою очередь, сгенерирует ошибку. Что мы делаем: Нажимаем F5 (продолжить выполнение программы), а затем во всплывающем окне выбираем Continue. В теории, Unity должна ожить и плюнуть в консоль ошибку, указав, где была загвоздка: Вздохнуть с облегчением. P.S. Способ с Visual Studio был позаимствован в блоге Unity. Там же можно прочитать, почему способ работает

Комментариев нет:

Отправить комментарий