square/SocketRocket — pull request #169 by jleandroperez (2014-04-25 20:23:53+00:00)
Title: Issue #156: Prevents crash in handleEvent method

We've been seeing crashes with the stack trace posted below. Our app is crashing during a block_copy operation, performed inside the method ```[SRWebSocket stream:handleEvent:]```.

Although i've been unable to directly reproduce this, i've added a couple safety measures that would prevent this from happening.

**Suspected scenario:**
- NSInputStream executes ``stream:handleEvent:`` in a BG thread.
- A the exact same time, SRWebSocket instance gets dealloc'ed.
- When ``stream:handleEvent:`` calls the dispatch_async routine, reference to self is no longer valid.

**Workaround:**
1. Updated ``stream:handleEvent:`` method: part of the code was moved to a second method, with a self-strong reference, stored in the stack.
2. Replaced 'self' with 'weakSelf', when appropriate.

**Any feedback will be very welcome. Thanks in advance, and congratulations on building this awesome project!**

**Crash Stack Trace:**

```
Crashed Thread: 3

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT

Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff894a9a1a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff894a8d18 mach_msg + 64
2 com.apple.CoreFoundation 0x00007fff94743fc5 __CFRunLoopServiceMachPort + 181
3 com.apple.CoreFoundation 0x00007fff947435e9 __CFRunLoopRun + 1161
4 com.apple.CoreFoundation 0x00007fff94742f25 CFRunLoopRunSpecific + 309
5 com.apple.HIToolbox 0x00007fff912eda0d RunCurrentEventLoopInMode + 226
6 com.apple.HIToolbox 0x00007fff912ed7b7 ReceiveNextEventCommon + 479
7 com.apple.HIToolbox 0x00007fff912ed5bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
8 com.apple.AppKit 0x00007fff8fc603de _DPSNextEvent + 1434
9 com.apple.AppKit 0x00007fff8fc5fa2b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
10 com.apple.AppKit 0x00007fff8fc53b2c -[NSApplication run] + 553
11 com.apple.AppKit 0x00007fff8fc3e913 NSApplicationMain + 940
12 libdyld.dylib 0x00007fff8b3c95fd start + 1

Thread 1:: Dispatch queue: com.apple.libdispatch-manager
0 libsystem_kernel.dylib 0x00007fff894ae662 kevent64 + 10
1 libdispatch.dylib 0x00007fff91d0743d _dispatch_mgr_invoke + 239
2 libdispatch.dylib 0x00007fff91d07152 _dispatch_mgr_thread + 52

Thread 2:
0 libsystem_kernel.dylib 0x00007fff894a9a1a mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00007fff894a8d18 mach_msg + 64
2 com.apple.CoreFoundation 0x00007fff94743fc5 __CFRunLoopServiceMachPort + 181
3 com.apple.CoreFoundation 0x00007fff947435e9 __CFRunLoopRun + 1161
4 com.apple.CoreFoundation 0x00007fff94742f25 CFRunLoopRunSpecific + 309
5 com.apple.AppKit 0x00007fff8fe0016e _NSEventThread + 144
6 libsystem_pthread.dylib 0x00007fff907cc899 _pthread_body + 138
7 libsystem_pthread.dylib 0x00007fff907cc72a _pthread_start + 137
8 libsystem_pthread.dylib 0x00007fff907d0fc9 thread_start + 13

Thread 3 Crashed:
0 libobjc.A.dylib 0x00007fff88bff7a2 objc_retain + 18
1 libsystem_blocks.dylib 0x00007fff89371580 _Block_copy_internal + 308
2 libdispatch.dylib 0x00007fff91d05546 _dispatch_Block_copy + 43
3 libdispatch.dylib 0x00007fff91d0b13f dispatch_async + 17
4 com.simperium.Simperium-OSX 0x0000000107fcd3aa -[SRWebSocket stream:handleEvent:] + 801
5 com.apple.CoreFoundation 0x00007fff94792c81 _signalEventSync + 385
6 com.apple.CoreFoundation 0x00007fff94792ac8 _cfstream_solo_signalEventSync + 328
7 com.apple.CoreFoundation 0x00007fff9479293f _CFStreamSignalEvent + 623
8 com.apple.CFNetwork 0x00007fff949ba16e CoreWriteStreamCFStreamSupport::coreStreamWriteEvent(__CoreWriteStream*, unsigned long) + 102
9 com.apple.CFNetwork 0x00007fff949ba0dd CoreWriteStreamClient::coreStreamEventsAvailable(unsigned long) + 53
10 com.apple.CFNetwork 0x00007fff94aeda65 CoreStreamBase::_callClientNow(CoreStreamClient*) + 53
11 com.apple.CFNetwork 0x00007fff949e3558 ___ZN14CoreStreamBase34_streamSetEventAndScheduleDeliveryEmh_block_invoke + 33
12 com.apple.CFNetwork 0x00007fff949d32ec ___ZNK17CoreSchedulingSet13_performAsyncEPKcU13block_pointerFvvE_block_invoke + 25
13 com.apple.CoreFoundation 0x00007fff9471db44 CFArrayApplyFunction + 68
14 com.apple.CFNetwork 0x00007fff949d31cb RunloopBlockContext::perform() + 115
15 com.apple.CFNetwork 0x00007fff949d3073 MultiplexerSource::perform() + 269
16 com.apple.CFNetwork 0x00007fff949d2ea2 MultiplexerSource::_perform(void*) + 72
17 com.apple.CoreFoundation 0x00007fff94752661 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
18 com.apple.CoreFoundation 0x00007fff94743d12 __CFRunLoopDoSources0 + 242
19 com.apple.CoreFoundation 0x00007fff9474349f __CFRunLoopRun + 831
20 com.apple.CoreFoundation 0x00007fff94742f25 CFRunLoopRunSpecific + 309
21 com.apple.Foundation 0x00007fff8d0e1adc -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 253
22 com.simperium.Simperium-OSX 0x0000000107fce528 -[_SRRunLoopThread main] + 291
23 com.apple.Foundation 0x00007fff8d0df76b __NSThread__main__ + 1318
24 libsystem_pthread.dylib 0x00007fff907cc899 _pthread_body + 138
25 libsystem_pthread.dylib 0x00007fff907cc72a _pthread_start + 137
26 libsystem_pthread.dylib 0x00007fff907d0fc9 thread_start + 13
```