ошибка lldb: переменная недоступна

Вот мои две строки кода:

NSString *frontFilePath = [[NSBundle mainBundle] pathForResource:[self.bookendFileNames objectAtIndex:self.randomIndex] ofType:@"caf"];
NSLog(@"frontFilePath = %@", frontFilePath );

Я ставлю точку останова на второй строке, и когда она там, я пытаюсь ее напечатать:

(lldb) po frontFilePath

Но я получаю следующую ошибку:

error: variable not available

Я сбит с толку, потому что, если я перешагну оператор NSLog, переменная действительно выведет на консоль.

Что бы это ни стоило, я пытаюсь отладить первую строку, поскольку иногда она возвращает NULL, хотя я пока не могу понять, почему.


person ari gold    schedule 23.10.2012    source источник
comment
Я думаю, что это всего лишь часть постоянных усилий Apple, направленных на то, чтобы сделать Xcode все менее и менее полезным и удобным для использования.   -  person Suboptimus    schedule 24.10.2012


Ответы (3)


Это артефакт отладки оптимизированного кода. Когда в настройках сборки включена оптимизация компилятора, он перемещает переменные между памятью и регистрами по своему усмотрению. В тот момент, когда вы просматриваете переменную в lldb, она может вообще не существовать в регистрах или памяти, даже если кажется, что она все еще должна быть доступна для отображения.

Возможно, это недостаток вывода отладочной информации компилятором. Иногда компилятор копирует переменную в регистр для ее использования и указывает только местоположение этого регистра в отладочной информации. Позже реестр переназначается для других целей; значение по-прежнему присутствует в стеке, но компилятор не сообщил отладчику, что это значение можно там найти.

Единственный способ действительно определить, недостаточно ли информации об отладке или значение действительно не существует в этой конкретной инструкции, - это изучить код сборки вручную. Как только вы включаете оптимизацию с помощью компилятора, исходный код становится слабым представлением того, что на самом деле выполняется в любом конкретном порядке.

Вместо того, чтобы слишком углубляться в дурацкий мир оптимизированной отладки кода, я настоятельно рекомендую отключить оптимизацию (уровень оптимизации в настройках сборки) для вашей сборки и отлаживать ее таким образом, если это вообще возможно. Если вам нужно отлаживать свое приложение с помощью оптимизации, убедитесь, что вы используете последний компилятор Apple LLVM, поддерживаемый вашим Xcode — всегда ведется работа по улучшению оптимизированной отладки кода, и вы хотите использовать самые передовые возможности. на сегодняшний день инструменты вы можете.

person Jason Molenda    schedule 24.10.2012
comment
Кстати, просто для ясности - я отвлекся от деталей в своем ответе - lldb говорит, что в этой конкретной точке инструкции он не знает, как найти значение вашей переменной. Переменная может быть недоступна в этот момент, или отладочная информация компилятора может быть просто недостаточно описательной, но lldb ничего не может сделать в этот момент, учитывая то, с чем она должна работать. - person Jason Molenda; 24.10.2012
comment
Что бы это ни стоило, для параметра Build Setting › Optimization Level не было установлено значение none в категории отладки. Он настроен на самый быстрый и наименьший в категории выпуска. Я предполагаю, что я в отладке, а не в выпуске, но я не совсем уверен, как это сказать. - person ari gold; 25.10.2012
comment
Я столкнулся с этим, когда в режиме выпуска вместо отладки, спасибо за этот ответ, он помог мне быстрее заметить это и вернуться :) - person Luke; 14.04.2013
comment
Отличный ответ, очень помог (аналогично: запуск в выпуске, окончательное тестирование). Я предлагаю всем зарегистрировать ошибку / нытье в Apple, чтобы изменить это сообщение об ошибке, которое говорит, что это означает, вместо того, чтобы иметь смысл только для людей, которые пишут компиляторы и отладчики. - person Adam; 15.09.2013
comment
У меня все еще есть эта проблема, хотя оптимизация определенно отключена. - person Paul Slocum; 13.01.2016
comment
@JasonMolenda У меня отключена оптимизация и я в режиме отладки, но проблема все еще существует - person onmyway133; 17.03.2016
comment
Посмотрим правде в глаза, Swift отстой!... это версия 3!!!, не бета, не альфа... 3! и мы говорим об Apple, самой богатой технологической компании в гууууууууууууу - person carlos_ms; 17.01.2017
comment
Swift настолько плох, что если у вас есть переменная с let, он оптимизирует ее, потому что думает, что вы больше не хотите ее изменять, так зачем беспокоиться о сохранении ссылки для вас, даже если у вас есть уровень оптимизации NONE . Замените свои let на var, и это может просто может сработать. - person carlos_ms; 17.01.2017
comment
@JasonMolenda, отключив оптимизацию, вы имеете в виду - установить для уровня оптимизации для конфигурации отладки значение «Нет»? - person gprasant; 24.08.2017
comment
А также, заглянув в настройки сборки, я нашел «Уровень оптимизации Apple LLVM 8.1» и «Уровень оптимизации компилятора Swift». Поскольку я вижу проблему, упомянутую в вопросе в коде Obj-C, достаточно ли изменить прежнюю настройку? - person gprasant; 24.08.2017
comment
Нет, такое бывает даже при полностью отключенной оптимизации. - person Eddie Sullivan; 21.05.2018
comment
@carlos_ms - это не быстро, это отстой, это Xcode, инструмент низкого качества. - person Duck; 20.03.2019

В Swift, возможно, начиная с Xcode 9 и до сих пор проблема в Xcode 10, это может даже возникнуть, когда оптимизация кода отключена в настройках сборки. Как указал здесь @carlos_ms, временное решение состоит в том, чтобы определить переменную как изменяемую, т.е.

Повернуть

let foo = Bar().string

в

var foo = Bar().string

чтобы заставить оптимизацию пропустить эту переменную. Обратите внимание, что это может работать не во всех случаях.

В этом случае вам может помочь старый добрый debugPrint().

person ff10    schedule 12.11.2018

Address Sanitizer в диагностике, похоже, тоже делает недоступными значения переменных.

Схемы > Выполнить > Диагностика > Дезинфекция адреса

person hEADcRASH    schedule 02.09.2020