Точка останова Xcode не работает внутри блока dispatch_async

Нашей команде очень нужна помощь в решении следующей проблемы, с которой мы столкнулись, поскольку она не позволяет нам отлаживать часть кода внутри блока dispatch_async.

Надеюсь, что я получу помощь или предложения о том, что делать дальше.

Проблема, с которой мы столкнулись, выглядит следующим образом:

Недавно мы столкнулись со странной проблемой, когда в Xcode 6 мы не можем сломаться в блоке dispatch_async.

- (void)viewDidLoad {

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);    

        dispatch_async(queue, ^{


        BOOL setRtn = TRUE;  //<- break point is set here but never break

        //call to function
        BOOL setFn = some_function();
        });

} 



- (BOOL) some_function()
{
     BOOL test = YES;   <- break point set here, breakpoint break!


     return test;
}

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

Однако, если мы установим точку останова внутри функции, вызываемой блоком dispatch_async, точка останова сработает!

Кто-нибудь еще сталкивается с той же проблемой?

Мы используем Xcode 6.1 и работаем над IOS8.1.

Пожалуйста, помогите, уже несколько дней схожу с ума, пытаясь решить эту проблему.


person garfieldmypet    schedule 08.10.2014    source источник


Ответы (4)


Оказывается, это было из-за стороннего фреймворка New Relic. Удалив ссылку на фреймворк New Relic, мы можем перейти внутрь блока dispatch_async.

Таким образом, для любого разработчика, работающего над проектом, в котором есть новый реликтовый плагин, вы можете временно удалить ссылку на плагин и добавить ее позже, когда ваш идентификатор отладки будет завершен.

Нам потребовалось несколько дней, чтобы выяснить это, и мы надеемся, что эта информация окажется полезной для всех.

person garfieldmypet    schedule 09.10.2014
comment
Есть идеи, почему это происходит с New Relic? Ваше решение сработало, мне просто интересно, почему это произошло в первую очередь. - person james; 21.07.2015
comment
Вместо того, чтобы полностью удалять NR, вы можете просто отключить инструментарий для dispatch_async, чтобы вы могли получать остальную часть мониторинга даже в dev. Смотрите мой ответ для получения дополнительной информации. - person dymocaptin; 12.08.2015

Как оказалось, инструменты Grand Central Dispatch действительно могут предотвращать точки останова в блоках dispatch_async. Вы можете отключить макросы GCD в своей среде, добавив в файл prefix.pch следующее:

#ifdef DEBUG
#undef dispatch_async 
#undef dispatch_sync 
#undef dispatch_after 
#undef dispatch_apply 
#undef _dispatch_once 
#endif
person dymocaptin    schedule 06.08.2015

В зависимости от настроенного уровня оптимизации сборки эта строка может быть скомпилирована таким образом, что ее невозможно сломать (ее можно даже удалить из вывода компилятора, если вы не используете эту переменную в блоке ).

Попробуйте установить оптимизацию на -O0 в настройках сборки.

person djromero    schedule 08.10.2014
comment
Мы проверили флаг ранее, и уровень оптимизации уже был установлен на -O0. Есть ли какие-либо другие настройки компилятора, которые нам нужно проверить? - person garfieldmypet; 08.10.2014
comment
Я тестировал в демонстрационном проекте; при -O0 останавливается на бп, при самой агрессивной оптимизации не останавливается. Сейчас я не знаю других флагов, которые могут повлиять на точки останова. Вы чистили и строили? - person djromero; 08.10.2014
comment
Мы также тестировали совершенно новый проект, и точка останова работает внутри dispatch_async. Однако для нашего существующего проекта, даже с оптимизацией, установленной на -O0, он не ломается. Да, мы снова очистили и собрали, переустановили Xcode, убедились, что символ генерации отладки включен, и все еще не работает. Что-нибудь еще, что мы можем сделать? - person garfieldmypet; 08.10.2014
comment
Одна вещь, которую мы обнаружили, заключается в том, что если мы установим точку останова непосредственно в строке dispatch_async, dispatch_async(queue, ^{ ‹-- точка останова здесь, она прервется с _85_‹function_name›_block_invoke. Дает ли это вам какое-либо представление о том, что случилось? - person garfieldmypet; 08.10.2014
comment
Не иначе как эта строка не оптимизировалась. Как и ожидалось. - person djromero; 08.10.2014

Я понимаю, что это не имеет особого смысла, но для меня танец Чистая папка сборки работал с некоторым кодом Swift 4.2, заключенным в DispatchQueue.main.async, который не останавливался в точке останова; после очистки и восстановления он теперь ломается, как и ожидалось.

Я использую Xcode 10.1, и мой параметр сборки уровня оптимизации уже был None -O0, как это предлагается в других ответах здесь.

person cdf1982    schedule 24.01.2019