Xcode/LLDB: Как получить информацию об исключении, которое было просто выдано?

Хорошо, поэтому предположите что моя точка останова в objc_exception_throw только что инициировал. Я сижу при подсказке отладчика, и я хочу получить еще некоторую информацию об объекте исключения. Где я нахожу его?

81
задан Karoy Lorentey 1 September 2015 в 17:58
поделиться

1 ответ

Объект исключения передается в качестве первого аргумента objc_exception_throw . LLDB предоставляет переменные $ arg1 .. $ argn для ссылки на аргументы в правильном соглашении о вызовах, что упрощает вывод сведений об исключении:

(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]

Убедитесь, что выбрали ] objc_exception_throw фрейм в стеке вызовов перед выполнением этих команд. См. «Расширенная отладка и средство очистки адресов» в видеороликах сеанса WWDC15, чтобы увидеть, как это выполняется на сцене.

Устаревшая информация

Если вы используете GDB, синтаксис для ссылки на первый аргумент зависит от соглашений о вызовах архитектуры, в которой вы работаете. Если вы выполняете отладку на реальном устройстве iOS, указатель на объект находится в регистре r0 . Чтобы распечатать его или отправить ему сообщение, используйте следующий простой синтаксис:

(gdb) po $r0
(gdb) po [$r0 name]
(gdb) po [$r0 reason]

В iPhone Simulator все аргументы функции передаются в стек, поэтому синтаксис значительно более ужасен. Самое короткое выражение, которое я смог построить, это * (id *) ($ ebp + 8) . Чтобы сделать вещи менее болезненными, я предлагаю использовать вспомогательную переменную:

(gdb) set $exception = *(id *)($ebp + 8)
(gdb) po $exception
(gdb) po [$exception name]
(gdb) po [$exception reason]

Вы также можете установить $ exception автоматически при срабатывании точки останова, добавив список команд в точку останова objc_exception_throw .

(Обратите внимание, что во всех случаях, которые я тестировал, объект исключения также присутствовал в регистрах eax и edx в момент достижения точки останова. Я не уверен, что ' Впрочем, так будет всегда.)

Добавлено из комментария ниже:

В lldb выберите кадр стека для objc_exception_throw , а затем введите эту команду:

(lldb) po *(id *)($esp + 4)
159
ответ дан 24 November 2019 в 09:34
поделиться