Стратегии отслеживания сбоев _objc_msgSend внутри блока dispatch_sync

Я получаю отчеты о сбоях (через отличный Hockey), указывающие на то, что у меня проблема с памятью в каком-то коде, который вызывается внутри блок dispatch_sync (по крайней мере, так я интерпретирую приведенный ниже фрагмент отчета о сбое). Мне вообще не удалось воссоздать этот сбой на моих тестовых устройствах (поэтому такие стратегии, как NSZombieEnabled, мне не помогают). Я рад внести изменения в код, чтобы сделать отчеты о сбоях более информативными (и в конечном итоге решить основную проблему), я просто не знаю, с чего начать. Какие-нибудь мысли?

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0xb000000c
Crashed Thread:  7
...
Thread 7 Crashed:
0   libobjc.A.dylib            0x3979bb66 _objc_msgSend + 6
1   libdispatch.dylib          0x39c898fb _dispatch_barrier_sync_f_invoke + 27
2   App                        0x00260f23 __48-[Foo displayLinkCallback]_block_invoke + 147
3   libdispatch.dylib          0x39c85103 _dispatch_call_block_and_release + 11
4   libdispatch.dylib          0x39c894bf _dispatch_async_redirect_invoke + 111
5   libdispatch.dylib          0x39c8a7e5 _dispatch_root_queue_drain + 225
6   libdispatch.dylib          0x39c8a9d1 _dispatch_worker_thread2 + 57
7   libsystem_pthread.dylib    0x39db4dff __pthread_wqthread + 299

dispatch_sync предоставляется статическая последовательная очередь. Возможно ли, что _objc_msgSend указывает на проблему со ссылкой на эту очередь, а не на проблему внутри блока?

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

Обновление (8 октября 2013 г.)

Добавление кода в соответствии с запросом (имена методов и переменных изменены, но все еще близки к оригиналу). Я подозреваю, что проблема где-то в копировании foo. Я надеялся, что этот вопрос даст стратегии для отладки этой ошибки. Если «проверка построчно» — лучшая стратегия для отладки _objc_msgSend сбоев внутри блока dispatch_sync, то это немного грустно, но я приму любую помощь, которую смогу получить на этом этапе.

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

- (void) displayLinkCallback
{
    dispatch_async(_frameDispatchQueue, ^{
        if ([_lock tryLock])
        {
            dispatch_sync(_renderQueueSerial, ^{
                NSObject *fooCopy = nil;
                BOOL bar = NO;

                // prevents deallocation during subsequent copy
                // _foo is set and/or its child objects changed 
                // many times per second by other threads)
                NSObject *foo = _foo;

                // copy foo 
                fooCopy = [foo copy];

                bar = [self needsBarGivenFoo:fooCopy];
                if (bar)
                {
                    _lastFoo = foo;
                    [self goFoo:fooCopy];
                }
                else
                {
                    [self noFoo:fooCopy];
                }
            });
            [_lock unlock];
        }
    });
}

person Jaysen Marais    schedule 14.09.2013    source источник
comment
Вы пробовали запускать Analyze в меню Product? Это запускает статический анализ и может помочь найти ошибки памяти и другие проблемы.   -  person BergQuester    schedule 14.09.2013
comment
@BergQuester да. Я запустил инструмент анализа проекта. Без вопросов. Спасибо за предложение, хотя   -  person Jaysen Marais    schedule 14.09.2013
comment
Похоже, что вся эта «ошибка» была отвлекающим маневром. Когда была решена отдельная ошибка записи памяти, проблема, упомянутая на этой странице, также исчезла. Спасибо тем, кто пытался помочь, и всем, кто столкнется с чем-то подобным в будущем, исследуйте Функции отладки Xcode Malloc   -  person Jaysen Marais    schedule 31.01.2015


Ответы (1)


Я бы предложил начать анализ с этих ссылок в исходных файлах. Этот символический журнал сбоев предполагает, что ваш сбой связан с чем-то в методе displayLinkCallback в классе Foo. Вероятно, вам стоит начать свое расследование там.

Это говорит о том, что у вас было нарушение сегментации. Но трудно проводить дальнейшую диагностику, не видя исходный код этого метода.

person Rob    schedule 14.09.2013
comment
На самом деле это не символический журнал сбоев. Если бы это было так, он бы показал имя файла и номер строки. Этот журнал показывает только имя метода и относительное смещение памяти. - person rmaddy; 14.09.2013
comment
@rmaddy Совершенно верно, это не номер строки. Но он символизируется, не так ли, потому что вы видите имя метода, а не необработанный журнал сбоев только с адресами памяти? Если вы посмотрите на несимволизированный журнал сбоев, у вас есть только адреса памяти. - person Rob; 14.09.2013
comment
Ты прав. После второго взгляда кажется, что он символизирован против dSYM, у которого не было никакой информации о номере строки, только таблица символов. - person rmaddy; 14.09.2013
comment
@Rob, @rmaddy, этот dSYM действительно содержит номера строк (отчеты о других сбоях в этой версии указывают на файлы и номера строк). Однако все это ломается, когда проблема возникает внутри отправки, отсюда и вопрос. Конечно, 0x00260f23 — это просто адрес _dispatch_barrier_sync_f_invoke? - person Jaysen Marais; 14.09.2013
comment
@JaysenMarais Отвечая на ваш первоначальный вопрос, я не думаю, что очередь сама по себе недействительна, но, вероятно, код в ней (например, когда я dispatch_sync блокирую сбой, я вижу что-то похожее на ваш журнал сбоев, но не идентичное , но если я использую недопустимую очередь, это совсем другое). Разобраться в журнале сбоев было бы проще, если бы мы могли видеть код. - person Rob; 14.09.2013