Использовать lldb для отладки собственных библиотек с помощью Xamarin
Отладочная документация Xamarin указывает:
Используйте встроенную поддержку отладки Xamarin Studio для отладки С# и другой код управляемых языков и использовать LLDB, когда вам нужно отлаживать C, С++ или Objective C, которые вы могли бы связать с вашим Xamarin.iOS проект.
Однако я не могу найти документацию о том, как использовать LLDB для отладки приложения Xamarin. Если я запустил приложение в iPhone Simulator и попытаюсь подключиться к нему с помощью LLDB, я получаю следующую ошибку:
(lldb) attach --pid 37993
Process 37993 exited with status = -1 (0xffffffff) lost connection
error: attach failed: lost connection
Прикрепление с помощью Xcode также не работает. Я пробовал разные варианты attach
, но никто из них не работал.
Может ли кто-нибудь указать мне в правильном направлении, как отлаживать приложения Xamarin с LLDB? Более того, это то, что я могу сделать на устройстве, а не только в симуляторе? Я не нашел никакой информации о том, как использовать LLDB для присоединения к процессу на устройстве.
Обновление
Похоже, процесс debugserver
сбой, когда я использую lldb
для подключения к моему двоичному файлу. Вот ссылка на отчет о сбое для debugserver
:
https://www.dropbox.com/s/9lizhl2quj9n0cc/debugserver_2015-07-07-131423_gauss.crash?dl=0
Обновление 2
Когда я запускаю dtruss
в приложении, он печатает системные вызовы, пока не встретит
dtrace: error on enabled probe ID 2475 (ID 194: syscall::ptrace:return): invalid user access in action #5 at DIF offset 0
которое происходит, когда что-то вызывает ptrace(PT_DENY_ATTACH, 0, 0, 0);
Почему PT_DENY_ATTACH
вызывается?
Обновление 3
Я проследил системный вызов ptrace
к этой функции: mono_assembly_init_with_opt
, который происходит очень рано в жизни программы. Вся эта функция выполняет вызов ptrace, поэтому, если я только вернусь раньше от этой функции, я могу выполнить отладку с lldb.
В принципе, я могу сделать:
(lldb) process attach --name AppName --waitfor
# when the process starts
(lldb) b mono_assembly_init_with_opt
(lldb) c
# when the thread breaks
(lldb) thread return 0
(lldb) c
и теперь я могу с радостью отладить с lldb.
Но я не должен был этого делать. Что-то не так с моей конфигурацией проекта (я могу отлаживать более простые приложения с lldb), или Xamarin является злым?
Ответы
Ответ 1
Это будет ограничение, наложенное Xamarin в пробной версии. После перехода на платную лицензию это уже не проблема. Несмотря на то, что на веб-сайте Xamarin говорится:
Когда вы начинаете Xamarin Trial, вы получаете доступ к полному Xamarin Набор функций для бизнеса в течение 30 дней.
Это явно не полный набор функций, поскольку они явно отключают присоединение lldb к приложению, если вы используете родную библиотеку. Я не уверен, причина для этого, может быть, кто-то из Xamarin может прокомментировать это.
Объяснение
Спасибо Джим Ингам за то, что он указал мне в правильном направлении. Способ отладчиков событий Xamarin от присоединения к приложению - это вызов ptrace с помощью PT_DENY_ATTACH
. Этот системный вызов позволяет процессу отклонять запросы на отладку. (Подробное объяснение).
Более того, вместо того, чтобы напрямую обращаться к функции ptrace
, Xamarin пытается скрыть вызов с помощью метода syscall
(ссылка).
Обход
Если вам действительно нужно отлаживать приложение и по-прежнему использовать пробную версию, это обходное решение. Системный вызов ptrace выполняется в функции mono_assembly_init_with_opt
, которая происходит очень рано в жизни программы. Эта функция ничего не делает и может быть пропущена. Так как функция называется right в начале процесса, нам нужно присоединить lldb до вызова функции.
Шаги следующие:
- Запустите lldb и дождитесь запуска приложения.
- Когда приложение запустится, добавьте точку останова для
mono_assembly_init_with_opt
- Возобновите приложение и, когда он остановится в этой функции, верните его раньше, не выполняя эту функцию.
- После этого вы можете использовать lldb или приложить Xcode к приложению и отладить свой собственный код, как обычно.
Шаги в lldb:
(lldb) process attach --name AppName --waitfor
(lldb) b mono_assembly_init_with_opt
(lldb) c
# when the thread breaks
(lldb) thread return 0
(lldb) c
Ответ 2
Codesigned apps в Mac OS X можно отлаживать, только если у них есть определенный атрибут, установленный в их приложении. Вы хотите что-то похожее:
<key>SecTaskAccess</key>
<array>
<string>allowed</string>
<string>debug</string>
</array>
Вы можете посмотреть справочную страницу taskgated
для несколько краткого описания этого процесса.
Обычно для проектов Xcode этот атрибут включается и вставлен в ваши отладочные сборки Xcode, поэтому вам не нужно ничего делать, чтобы это произошло.
Я не знаю, как работает Xamarin, но возможно, что он не устанавливает этот атрибут. В более старых системах OS X root может отлаживать что угодно, поэтому вы можете попробовать sudo -s
, а затем отладить оттуда. Но, начиная с Йосемити, просьба не отлаживаться более широко признана...
Ответ 3
Вы пытались использовать pid из Activity Monitor? Просто введите имя приложения в поле поиска в Activity Monitor при запуске в Debug.
Если он все еще не работает, вы можете попробовать просто создать новый проект и подключиться к нему, чтобы исключить любую конфигурацию проекта.