LLDB и <<регистр XY недоступен> "
Иногда (что довольно часто), когда я пытаюсь отлаживать аварии из iPad-приложения, LLDB решает не быть слишком полезным, и печать переменных (стек или членов класса) не работает.
Если я щелкнул правой кнопкой мыши (или CTRL + щелчок) в окне отладки слева, а затем "Печать описания", я получаю сообщения об ошибках, например:
Printing description of error:
(NSURLError *) error = <register sp is not available>
или
Printing description of error:
(NSURLError *) error = <register ebp is not available>
Если я попытаюсь использовать консоль отладки, я получаю что-то вроде этого:
(lldb) po error
(NSError *) $3 = 0x2124fc10 [no Objective-C description available]
После этого правый щелчок начинает работать и дает следующее:
Printing description of error:
(NSURLError *) error = 0x2124fc10
Но все, что я получаю, это адрес памяти, он не может называть description
на нем.
Если я попытаюсь отправить сообщение description
, это произойдет:
(lldb) po [error description]
error: Execution was interrupted.
The process has been returned to the state before execution.
Так что это тоже не полезно.
Что можно сделать, чтобы снова использовать отладчик? Мне отчаянно приходится ловить крах, но каждый раз, когда я могу спровоцировать это, это происходит, и я не знаю, как добраться до ядра ошибки.
Я googled для "register not available lldb", но ничего не нашел, только некоторые журналы pastebin, никаких ответов.
FYI: Используя Xcode 4.5.2, iOS SDK 6.0, компилируя "Debug" -Profile, никаких оптимизаций не включается, LLDB Debugger, цель развертывания iOS 5.0, происходит при отладке в Simulator или на устройстве (iPad 1 и 3, iPhone 4S, iPhone 3GS), отлаженное приложение использует GCD довольно широко.
Ответы
Ответ 1
Вы попадаете на ошибку в lldb в Xcode 4.5.x с ее изменчивым списком регистра на i386.
Регистры попадают в два класса: энергозависимые и нелетучие (или сберегаемые пользователем). Когда функция вызывает другую функцию, все "изменчивые" регистры могут перезаписывать их содержимое. Все сохраненные регистры с энергонезависимой памятью будут сохранены вызываемой функцией (функция вызываемого абонента) до их повторного использования, а их предыдущие значения будут восстановлены до возвращения.
Иногда информация об отладке будет указывать, что переменная хранится в энергозависимом регистре. Если эта функция находится в середине вашего стека и вы хотите изучить эту переменную, отладчик не может восстановить это значение регистра - он потерян. gdb просто скопировал значение изменчивого регистра до середины стека и распечатал переменную с (потенциально) фиктивным значением, что привело бы к тому, что разработчики были бы очень смущены.
lldb знает разницу между энергозависимыми и энергонезависимыми регистрами и не позволит повторно использовать летучие регистры в середине такого стека - они скажут, что вместо этого значение регистра недоступно.
К сожалению, в этом случае вы видите, что lldb утверждает, что он не может восстановить доступные переменные. Они ошибочно классифицируются как неустойчивые, когда они должны быть энергонезависимыми. Без проведения многогосударственной инспекции, вам будет нелегко работать. Единственное решение здесь - возобновить выполнение, пока вы снова не вернетесь в эту функцию (т.е. Теперь это кадр 0), а затем все значения регистра будут правильно отмечены как доступные.
Это исправлено в Xcode 5, выпущенном в сентябре 2013 года.