zwopple / PocketSocket

Objective-C websocket library for building things that work in realtime on iOS and OS X.
Other
414 stars 129 forks source link

Fix an "unrecognized selector sent to instance" crash #79

Open eunikolsky opened 5 years ago

eunikolsky commented 5 years ago

An app using PocketSocket crashes occasionally with this information:

Fatal Exception: NSInvalidArgumentException
-[SomeDelegate webSocketDidFlushOutput:]: unrecognized selector sent to instance 0x123456789
0  CoreFoundation                 0x88881ad8c __exceptionPreprocess
…
5  PocketSocket                   0x8888d5004 __43-[PSWebSocket notifyDelegateDidFlushOutput]_block_invoke (PSWebSocket.m:668)
6  libdispatch.dylib              0x88880caa0 _dispatch_call_block_and_release
…

The notifyDelegateDidFlushOutput function checks if the delegate responds to the webSocketDidFlushOutput: selector before sending it. The only possible cause for the crash is when the delegate changes between the check and the call because the function is not atomic. Added testChangingDelegateWhileFlushingOutputShouldNotCrashWithUnrecognizedSelector can reproduce the crash very quickly and consistently.

The fix here is to capture the delegate strongly while the function is running to work with the same instance. The patch fixes the crash in all similar places in PSWebSocket, as well as in PSWebSocketServer.