objc_msgSend() и EXC_BAD_ACCESS в приложении cocoa

#objective-c #cocoa #macos #exc-bad-access

#objective-c #cocoa #macos #исключение-bad-access

Вопрос:

Вообще говоря, как нам избежать сбоев objc_msgSend() в наших приложениях для Mac? Кроме того, как нам избежать сбоев EXC_BAD_ACCESS? Почему мы это получаем? Как мы можем справиться с такого рода ошибками? Их количество в нашем приложении увеличивается, и мы хотели бы попросить совета и помощи по этому вопросу.

Мы используем XCode 3.2.5, и наш проект является проектом Cocoa, использующим язык Objective-C. Наш веб-сервис представляет собой ASP на базе IIS.Веб-сайт Net (откуда мы можем загружать XML-файлы и изображения).

Мы разрабатываем cocoa-приложение для Mac, и мы сталкиваемся с этим примерно два раза за десять попыток запуска приложения. В этом приложении есть приложение sketch, и когда мы запускаем приложение, оно просто зависает и выходит из строя в течение 1 минуты, ничего не делая. Некоторые функции, которые выполняет это приложение, это:

  • загружайте xml из Интернета и интерпретируйте в нашем приложении
  • войдите в веб-службу
  • имеет блокнот для рисования
  • имеет таймер
  • функции перетаскивания
  • загрузка XML-данных
  • загружайте изображения и отображайте в нашем приложении

Сбой не ограничивается периодом после запуска приложения. Иногда при манипуляциях с программой, таких как перетаскивание, загрузка набора данных и выполнение функций добавления / редактирования / удаления в нашем приложении для Mac, приложение также вылетает.

Честно говоря, мы относительно новички в этой платформе разработки и среде, и мы все еще учимся. Можете ли вы помочь нам в этом вопросе? Нужны какие-то ресурсы или подсказки о том, где мы сделали это неправильно? Большое спасибо и больше энергии всем присутствующим.


Следующий пример отчета о сбое:

 Process:         Sketch [63065]
Path:            /Users/william_hooley_27Inch/Desktop/untitled folder/MacGlass.app/Contents/MacOS/Sketch
Identifier:      com.apple.CocoaExamples.Sketch
Version:         1.049 (48.1)
Code Type:       X86 (Native)
Parent Process:  launchd [116]
Date/Time:       2011-04-14 13:12:15.421  1000
OS Version:      Mac OS X 10.6.5 (10H574)
Report Version:  6
Interval Since Last Report:          714907 sec
Crashes Since Last Report:           17
Per-App Interval Since Last Report:  206437 sec

Per-App Crashes Since Last Report:   5
Anonymous UUID:                     
086C860F-E28E-4256-84F9-9692782AAD01
Exception Type:  EXC_BAD_ACCESS
(SIGBUS) Exception Codes:
KERN_PROTECTION_FAILURE at
0x0000000000000044 Crashed Thread:  0 
Dispatch queue: com.apple.main-thread
Thread 0 Crashed:  Dispatch queue:
com.apple.main-thread 0  
com.apple.AppKit             
0x91a8e6cb
_recursiveInvalidateCachedVisibleRectValue
  24 1   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
2   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 3   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
4   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 5   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
6   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 7   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
8   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 9   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
10  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 11  com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
12  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 13  com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction   224
14  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
  90 15  com.apple.AppKit              0x91a8e2e1 -[NSView _setSuperview:]  
684 16  com.apple.AppKit             
0x91a8db02 -[NSView addSubview:]   383
17  com.apple.CocoaExamples.Sketch
0x00094cbf -[viewTasksDisplay Appear:]
  242 18  com.apple.CocoaExamples.Sketch
0x000c2e8f -[MainWindow
ShowLeftScreen:]   964 19 
com.apple.CocoaExamples.Sketch
0x0003e301 -[viewOptionMenuItemmouseDown:]   2055 20 
com.apple.AppKit             
0x91bc6c68 -[NSWindow sendEvent:]  
5549 21  com.apple.AppKit             
0x91adf817 -[NSApplication sendEvent:]
  6431 22  com.apple.AppKit              0x91a732a7 -[NSApplication run]   917
23  com.apple.AppKit             
0x91a6b2d9 NSApplicationMain   574 24 
com.apple.CocoaExamples.Sketch
0x0001b33e main   30 25 
com.apple.CocoaExamples.Sketch
0x00001eba start   54 Thread 1: 
Dispatch queue:
com.apple.libdispatch-manager 0  
libSystem.B.dylib            
0x98002982 kevent   10 1  
libSystem.B.dylib            
0x9800309c _dispatch_mgr_invoke   215
2   libSystem.B.dylib            
0x98002559 _dispatch_queue_invoke  
163 3   libSystem.B.dylib            
0x980022fe _dispatch_worker_thread2  
240 4   libSystem.B.dylib            
0x98001d81 _pthread_wqthread   390 5  
libSystem.B.dylib            
0x98001bc6 start_wqthread   30 Thread
2: 0   libSystem.B.dylib            
0x97fdc0fa mach_msg_trap   10 1  
libSystem.B.dylib            
0x97fdc867 mach_msg   68 2  
com.apple.CoreFoundation     
0x995f837f __CFRunLoopRun   2079
  

Еще один отчет о сбое:

 Date/Time:       2011-04-14 13:27:02
 1000 OS Version:      10.6.5 (Build 10H574) Architecture:    x86_64 Report
Version:  6 Command:         MacGlass
Path:           
/Users/william_hooley_27Inch/Desktop/untitled
folder/MacGlass.app/Contents/MacOS/Sketch
Version:         1.050 (48.1) Parent: 
launchd [116] PID:             63101
Event:           hang Duration:       
3.58s (sampling started after 2 seconds) Steps:           16 (100ms
sampling interval) Pageins:         0
Pageouts:        0 Process:        
Sketch [63101] Path:           
/Users/william_hooley_27Inch/Desktop/untitled
folder/MacGlass.app/Contents/MacOS/Sketch
UID:             501   Thread edef3d4 
DispatchQueue 100   User stack:
    16 start   54 (in Sketch) [0x1f6a]
      16 main   30 (in Sketch) [0x1b3ee]
        16 NSApplicationMain   574 (in AppKit) [0x91a6b2d9]
          16 -[NSApplication run]   821 (in AppKit) [0x91a73247]
            16 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
  156 (in AppKit) [0x91ab0fce]
              16 _DPSNextEvent   847 (in AppKit) [0x91ab178d]
                16 BlockUntilNextEventMatchingListInMode
  81 (in HIToolbox) [0x95bd0bd6]
                  16 ReceiveNextEventCommon   354 (in
HIToolbox) [0x95bd0d51]
                    16 RunCurrentEventLoopInMode   392 (in
HIToolbox) [0x95bd0f9c]
                      16 CFRunLoopRunInMode   97 (in
CoreFoundation) [0x995f7291]
                        16 CFRunLoopRunSpecific   452 (in
CoreFoundation) [0x995f7464]
                          16 __CFRunLoopRun   8059 (in CoreFoundation) [0x995f9adb]
                            16 __NSFireTimer   141 (in Foundation) [0x972c39b0]
                              16 _handleWindowNeedsDisplay   696 (in AppKit) [0x91adb28a]
                                16 -[NSWindow displayIfNeeded]   204 (in AppKit) [0x91aa9d40]
                                  16 -[NSView displayIfNeeded]   818 (in AppKit) [0x91ae0a57]
                                    16 -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
  4122 (in AppKit) [0x91b801cf]
                                      16 CAViewEndDraw   134 (in QuartzCore)
[0x961bd926]
                                        16 pthread_cond_wait$UNIX2003   73 (in
libSystem.B.dylib) [0x9800b9f8]
                                          16 __semwait_signal   10 (in
libSystem.B.dylib) [0x9800a0a6]  
Kernel stack:
    15 semaphore_wait_continue   0 [0x22a3dd]
    1 lo_alltraps   454 [0x2a08a6]
      1 i386_astintr   47 [0x2a9a9a]
        1 ast_taken   247 [0x219107]
          1 bsd_ast   806 [0x489088]
            1 postsig   432 [0x4861df]
              1 exit1   449 [0x47ab28]
                1 task_terminate_internal   315
[0x22c56a]
  

Комментарии:

1. И распространенной причиной EXC_BAD_ACCESS является неправильное управление памятью. Используете ли вы сборку мусора в своем приложении?

2. Я рекомендую прочитать: Итак, вы потерпели крах в objc_msgSend()

Ответ №1:

Обычная причина чего-то подобного — чрезмерное высвобождение объектов. Если вы запускаете свой код с помощью NSZombieEnabled, вывод на консоль должен дать вам подсказку о том, где искать.

В качестве альтернативы, если это приложение для Macintosh, ориентированное на версию 10.5 или выше, вы можете включить сборку мусора и вообще не беспокоиться о сохранении и выпуске.

Ответ №2:

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

(gdb) x / s $ r1

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

Комментарии:

1. ![введите описание изображения здесь][1] [1]: i.stack.imgur.com/otnqT.png Я делаю это неправильно?

2. Приведенный выше ответ был для gdb, но из вашего скриншота ясно, что вы используете lldb (который является отладчиком по умолчанию начиная с XCode 4.3). Информацию о том, как использовать lldb, можно найти здесь: lldb.llvm.org/tutorial.html

3. $ r1 — это не тот регистр, в котором он взорвался для меня с iOS 8. Следует смотреть на трассировку стека по мере изменения ситуации

Ответ №3:

Второй отчет о сбое — это не сбой, это отчет о зависании. Это означает, что ваше приложение работало медленно, а не зависало.

В общем, прочитайте и полностью поймите рекомендации по управлению памятью Cocoa; ошибки в управлении памятью являются причиной подавляющего большинства сбоев в приложениях Cocoa. Руководство можно найти здесь: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

Вы также должны иметь возможность использовать такие инструменты, как отладчик Xcode и инструмент Zombies в Instruments, для сбора более подробной информации о сбоях.

Ответ №4:

Я смог найти проблемный селектор с помощью lldb, но подход для меня отличался от описанного в ответе выше, используя семантику gdb и более раннюю версию iOS (в настоящее время я работаю с iOS 8)

Моя трассировка стека начиналась так:

 libobjc.A.dylib`objc_msgSend:
0x10c160000:  testq  %rdi, %rdi
0x10c160003:  jle    0x10c160068        ; objc_msgSend   104
0x10c160005:  movq   (%rdi), %r11
0x10c160008:  movq   %rsi, %r10
0x10c16000b:  andl   0x18(%r11), %r10d  <== EXC_BAD_ACCESS
  

В приглашении lldb я выполнил следующее:

 (lldb) register read -G s r10
     r10 = "xffffffc16xffffffa4tx01"  "isKindOfClass:"
  

Ответ №5:

Я только что решил проблему EXC_BAD_ACCESS в objc_msgSend, найдя, где я перезаписал конец строки, повредив объект в хранилище….

Ответ №6:

Проблема для меня заключалась в том, что я вызвал обработчик UIAleraction из селектора, который не был UIAleraction