I get these crashes time by time. Wondering what could cause this.
In file WebSocket.swift line 259 I see this:
stream.close()
Full stack trace from Crashlytics:
Crashed: com.vluxe.starscream.websocket
0 CoreFoundation 0x19262f990 CFHash + 360
1 CoreFoundation 0x19262c830 <redacted> + 164
2 CoreFoundation 0x19262c770 CFDictionaryGetValue + 224
3 CoreFoundation 0x1926a5c64 <redacted> + 184
4 CoreFoundation 0x1927241b0 <redacted> + 168
5 Starscream 0x1012550b0 FoundationStream.cleanup() (WebSocket.swift:259)
6 Starscream 0x101256198 protocol witness for WSStream.cleanup() in conformance FoundationStream (WebSocket.swift)
7 Starscream 0x10126b2b0 specialized closure #1 in WebSocket.initStreamsWithData(_:_:) (WebSocket.swift:734)
8 Starscream 0x10127180c partial apply for closure #1 in WebSocket.initStreamsWithData(_:_:) (WebSocket.swift)
9 Starscream 0x101268b00 specialized closure #1 in FoundationStream.connect(url:port:timeout:ssl:completion:) (WebSocket.swift:225)
10 Starscream 0x1012719bc partial apply for closure #1 in FoundationStream.connect(url:port:timeout:ssl:completion:) (WebSocket.swift)
11 Starscream 0x101254204 thunk for @callee_owned () -> () (WebSocket.swift)
12 libdispatch.dylib 0x192126714 <redacted> + 24
13 libdispatch.dylib 0x1921266d4 <redacted> + 16
14 libdispatch.dylib 0x192134d20 <redacted> + 528
15 libdispatch.dylib 0x192129a08 <redacted> + 340
16 libdispatch.dylib 0x192135c04 <redacted> + 404
17 libdispatch.dylib 0x19213c3fc <redacted> + 644
18 libsystem_pthread.dylib 0x19239b398 _pthread_wqthread + 1024
19 libsystem_pthread.dylib 0x19239af8c start_wqthread + 4

Are you seeing a call to FoundationStream.cleanup() on your main or other thread when this happens? Click to open the rest of your threads in fabric on that issue and see if another thread is also calling it.
I get crashes like this where WSStream.cleanup() is called on both threads simultaneously.
I think there is a race condition here between the threads when stream.close() takes some amount of time to execute. One temporary solution might be to nil the old stream and construct a new one when reconnecting, instead of reusing the same one?
But I think what should be done to fix this is to check if the stream is already closing and, if necessary, wait for it to finish doing so before reopening the stream.
@daltoniam let me know if I am interpreting this right.
com.apple.main-thread
0 libsystem_kernel.dylib 0x182aa4138 __psynch_mutexwait + 8
1 libsystem_pthread.dylib 0x182bbf960 _pthread_mutex_lock_wait + 96
2 libsystem_pthread.dylib 0x182bbf8a4 _pthread_mutex_lock_slow$VARIANT$armv81 + 244
3 CoreFoundation 0x182ec7574 _CFStreamUnscheduleFromRunLoop + 152
4 CoreFoundation 0x182f45cc0 _CFStreamSetDispatchQueue + 168
5 Starscream 0x1051f3b94 FoundationStream.cleanup() (WebSocket.swift:259)
6 Starscream 0x1051f4c7c protocol witness for WSStream.cleanup() in conformance FoundationStream (WebSocket.swift)
7 Starscream 0x105209424 specialized WebSocket.initStreamsWithData(_:_:) (WebSocket.swift:734)
8 Starscream 0x1051f7b2c WebSocket.createHTTPRequest() (WebSocket.swift:615)
...etc
Crashed: com.vluxe.starscream.websocket
0 CoreFoundation 0x182e512c0 CFHash + 360
1 CoreFoundation 0x182e4e160 CFBasicHashFindBucket + 164
2 CoreFoundation 0x182e4e0a0 CFDictionaryGetValue + 224
3 CoreFoundation 0x182ec7594 _CFStreamUnscheduleFromRunLoop + 184
4 CoreFoundation 0x182f45cc0 _CFStreamSetDispatchQueue + 168
5 Starscream 0x1051f3b40 FoundationStream.cleanup() (WebSocket.swift:254)
6 Starscream 0x1051f4c7c protocol witness for WSStream.cleanup() in conformance FoundationStream (WebSocket.swift)
7 Starscream 0x10520638c specialized WebSocket.disconnectStream(_:runDelegate:) (WebSocket.swift:734)
8 Starscream 0x1051f968c protocol witness for WSStreamDelegate.streamDidError(error:) in conformance WebSocket (WebSocket.swift)
9 Starscream 0x105207334 specialized FoundationStream.stream(_:handle:) (WebSocket.swift:298)
10 Starscream 0x1051f4734 @objc FoundationStream.stream(_:handle:) (WebSocket.swift)
11 CoreFoundation 0x182ec72d0 _signalEventSync + 212
12 CoreFoundation 0x182f46178 ___signalEventQueue_block_invoke + 24
13 libdispatch.dylib 0x18290ea54 _dispatch_call_block_and_release + 24
14 libdispatch.dylib 0x18290ea14 _dispatch_client_callout + 16
15 libdispatch.dylib 0x18294d04c _dispatch_queue_serial_drain$VARIANT$armv81 + 520
16 libdispatch.dylib 0x18294d9bc _dispatch_queue_invoke$VARIANT$armv81 + 340
17 libdispatch.dylib 0x18294e3a8 _dispatch_root_queue_drain_deferred_wlh$VARIANT$armv81 + 384
18 libdispatch.dylib 0x1829564b0 _dispatch_workloop_worker_thread$VARIANT$armv81 + 640
19 libsystem_pthread.dylib 0x182bb6f1c _pthread_wqthread + 932
20 libsystem_pthread.dylib 0x182bb6b6c start_wqthread + 4
@flagoworld It doesn't crash on main thread, but on com.vluxe.starscream.websocket
Right, but is there a call to the same close() func on another thread at the same time the websocket thread crashed? See my stack trace.
@flagoworld You're right! .cleanup is called from two threads.
Facing same issue any update on how to fix ??
This appears to fix for me:
https://github.com/daltoniam/Starscream/pull/476
Please review and use at your own risk. I am not familiar enough with the codebase to claim that this is the correct fix. It's more of a suggestion and educated guess.
We get the same crash (cleanup) for a while now.
The first suggested solution by the repository maintainer (0.5s delay on reconnect) helped reducing crashes a lot, but it hasn't fixed all of them.
It seems we still have 2 separate concurrency issue :
connect on one thread and cleanup on another, causing a crash at stream.close() https://github.com/daltoniam/Starscream/blob/31f522155a4d6323cd1aaefb8dbc140ced7be1ca/Sources/WebSocket.swift#L259 with the other thread (connect) onCFReadStreamSetDispatchQueue(inStream, FoundationStream.sharedWorkQueue)
https://github.com/daltoniam/Starscream/blob/31f522155a4d6323cd1aaefb8dbc140ced7be1ca/Sources/WebSocket.swift#L208cleanup on one thread and cleanup on another, causing a crash at stream.close() https://github.com/daltoniam/Starscream/blob/31f522155a4d6323cd1aaefb8dbc140ced7be1ca/Sources/WebSocket.swift#L254 while the other thread is at stream.close() https://github.com/daltoniam/Starscream/blob/31f522155a4d6323cd1aaefb8dbc140ced7be1ca/Sources/WebSocket.swift#L259@flagoworld I believe that your fix will help for the cleanup & cleanup case, but will not for the connect & cleanup one, so i believe the real "fix" is to put the locks around all the calls to .close() and *SetDispatchQueue and not only in the cleanup method
Version 3.0.5 has been released. It has a fix as found in #476.
Most helpful comment
Are you seeing a call to FoundationStream.cleanup() on your main or other thread when this happens? Click to open the rest of your threads in fabric on that issue and see if another thread is also calling it.
I get crashes like this where WSStream.cleanup() is called on both threads simultaneously.
I think there is a race condition here between the threads when stream.close() takes some amount of time to execute. One temporary solution might be to nil the old stream and construct a new one when reconnecting, instead of reusing the same one?
But I think what should be done to fix this is to check if the stream is already closing and, if necessary, wait for it to finish doing so before reopening the stream.
@daltoniam let me know if I am interpreting this right.