Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception thrown when invoking [_channel unsubscribe] #640

Closed
liuzhen2008 opened this issue Oct 20, 2017 · 17 comments
Closed

Exception thrown when invoking [_channel unsubscribe] #640

liuzhen2008 opened this issue Oct 20, 2017 · 17 comments
Assignees
Labels
bug Something isn't working. It's clear that this does need to be fixed.

Comments

@liuzhen2008
Copy link

We sometimes experience an exception being thrown for [_channel unsubscribe];

The full stacktrace can be found below. This happens intermittently for us and we can't reliably reproduce the issue.

for now we just added try catch around [unsubscribe] hopefully it doesn't crash our users anymore.

Fatal Exception: NSGenericException
*** Collection <__NSArrayM: 0x173c0540> was mutated while being enumerated.
-[ARTEventEmitter resetListeners]
 Raw Text

Fatal Exception: NSGenericException
0  CoreFoundation                 0x1b4bfb3d __exceptionPreprocess
1  libobjc.A.dylib                0x1a747067 objc_exception_throw
2  CoreFoundation                 0x1b4bf5e1 -[NSException name]
3  MY TEST CI                 0x1f7805 -[ARTEventEmitter resetListeners] (ARTEventEmitter.m:258)
4  MY TEST CI                 0x20cb15 -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:301)
5  MY TEST CI                 0x16d815 -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:25)
6  MY TEST CI                 0x153001 -[BroadcastDisplayerViewController dismissController] (BroadcastDisplayerViewController.m:353)
7  UIKit                          0x207263b5 -[UIApplication sendAction:to:from:forEvent:]
8  UIKit                          0x20726349 -[UIControl sendAction:to:forEvent:]
9  UIKit                          0x20710979 -[UIControl _sendActionsForEvents:withEvent:]
10 UIKit                          0x20725c85 -[UIControl touchesEnded:withEvent:]

@mattheworiordan
Copy link
Member

mattheworiordan commented Oct 23, 2017

Sorry to hear this. @tcard @ricardopereira would one of you please look at this?

@mattheworiordan mattheworiordan added the bug Something isn't working. It's clear that this does need to be fixed. label Oct 23, 2017
@ricardopereira
Copy link
Contributor

@tcard Adding a mutex lock should be enough, right? https://github.com/ably/ably-ios/blob/master/Source/ARTEventEmitter.m#L234-L248

@tcard
Copy link
Contributor

tcard commented Oct 23, 2017

@ricardopereira It is supposed to be in a mutex already. unsubscribe dispatches its operation on messagesEventEmitter to the internal queue, and every operation on messagesEventEmitter should also be dispatched to that queue. But obviously some isn't.

So somewhere must exist a method call on messagesEventEmitter that isn't inside a dispatch_a?sync. I couldn't find any from a quick look.

@liuzhen2008 Can you confirm which version of the library are you on? Those line numbers don't seem to correspond to a recent one.

@liuzhen2008
Copy link
Author

@tcard

This is my podfile.lock

  - Ably (1.0.3):
    - msgpack (= 0.1.8)
    - SocketRocket (= 0.5.1)

We'll update the ably library as well.

@tcard
Copy link
Contributor

tcard commented Oct 25, 2017

@liuzhen2008 That most likely will fix the issue, since we had widespread thread-safety bugs before 1.0.8. I'll tentatively mark this as closed, but please do open again if the issue persist. Thanks!

@tcard tcard closed this as completed Oct 25, 2017
@liuzhen2008
Copy link
Author

@tcard We upgraded to ably 1.0.9

Podfile.lock as below:

- Ably (1.0.9):
    - KSCrashAblyFork (= 1.15.8-ably-1)
    - msgpack (= 0.1.8)
    - SocketRocket (= 0.5.1)

Still getting a crash occasionally. Try/catch doesn't even catch this time.

Crashed: io.ably.main
0  libdispatch.dylib              0x1807e2f20 _dispatch_barrier_sync_f_slow + 596
1  MY TEST CI               0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
2  MY TEST CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
3  MY TEST CI                 0x100153a9c -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:27)
4  MY TEST CI                 0x100134378 -[BroadcastDisplayerViewController garbageCollectAbly] (BroadcastDisplayerViewController.m:157)
5  MY TEST CI                 0x1001342e8 -[BroadcastDisplayerViewController dealloc] (BroadcastDisplayerViewController.m:152)
6  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
7  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
8  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
9  Foundation                     0x18236607c -[__NSObserver dealloc] + 128
10 MY TEST CI                 0x1001f2644 -[ARTEventListener removeObserver] (ARTEventEmitter.m:88)
11 MY TEST CI                 0x1001f41c8 -[ARTEventEmitter resetListeners] (ARTEventEmitter.m:245)
12 MY TEST CI                 0x100214dd8 -[ARTRealtimeChannel _unsubscribe] (ARTRealtimeChannel.m:418)
13 MY TEST CI                0x100214ca0 __33-[ARTRealtimeChannel unsubscribe]_block_invoke (ARTRealtimeChannel.m:412)

@ricardopereira
Copy link
Contributor

@liuzhen2008 Unfortunately, I can't reproduce the problem.

Does it happen in a production app? Could you tell us the app bundle identifier?
Are you using Ably in different queues?

@liuzhen2008
Copy link
Author

liuzhen2008 commented Nov 8, 2017

@ricardopereira I am not sure with the "different queues" part.

Is there a specific queue that i have to use when subscribing/unsubscribing from Ably? Would it be safer if i always execute subscribe/unsubcribe in main queue?

com.charly.charlyUser is our app identifier.
We are currently using 1.0.3 but we briefly used 1.0.9 and experienced that un-try-catch-able crash.

@ricardopereira
Copy link
Contributor

ricardopereira commented Nov 8, 2017

@ricardopereira I am not sure with the "different queues" part.

@liuzhen2008 Sorry. If you're using the library in different threads?

Since we can't reproduce the problem, the only way we can debug this is by having the full stack trace of the exception. Do you have access to it and could you share it with us please?

@liuzhen2008
Copy link
Author

liuzhen2008 commented Nov 8, 2017

@ricardopereira I have full stack trace here.

But go back to my question - would you say it is safer if i always run subscribe/unsubcribe in main queue?

# Crashlytics - plaintext stacktrace downloaded by Charly Developer at Wed, 08 Nov 2017 15:48:40 GMT
# Organization: Getcharly
# Platform: ios
# Application: charly
# Version: 2.7.1 (276)
# Bundle Identifier: com.charly.charlyUser
# Issue #: 336
# Date: 2017-10-30T20:25:00Z
# OS Version: 10.2.1 (14D27)
# Device: iPhone 6
# RAM Free: 2.4%
# Disk Free: 87.1%

#0. Crashed: io.ably.main
0  libdispatch.dylib              0x1807e2f20 _dispatch_barrier_sync_f_slow + 596
1  Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
2  Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
3  Charly Prod CI                 0x100153a9c -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:27)
4  Charly Prod CI                 0x100134378 -[BroadcastDisplayerViewController garbageCollectAbly] (BroadcastDisplayerViewController.m:157)
5  Charly Prod CI                 0x1001342e8 -[BroadcastDisplayerViewController dealloc] (BroadcastDisplayerViewController.m:152)
6  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
7  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
8  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
9  Foundation                     0x18236607c -[__NSObserver dealloc] + 128
10 Charly Prod CI                 0x1001f2644 -[ARTEventListener removeObserver] (ARTEventEmitter.m:88)
11 Charly Prod CI                 0x1001f41c8 -[ARTEventEmitter resetListeners] (ARTEventEmitter.m:245)
12 Charly Prod CI                 0x100214dd8 -[ARTRealtimeChannel _unsubscribe] (ARTRealtimeChannel.m:418)
13 Charly Prod CI                 0x100214ca0 __33-[ARTRealtimeChannel unsubscribe]_block_invoke (ARTRealtimeChannel.m:412)
14 libdispatch.dylib              0x1807d21bc _dispatch_client_callout + 16
15 libdispatch.dylib              0x1807df7f0 _dispatch_barrier_sync_f_invoke + 84
16 Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
17 Charly Prod CI                 0x100153a9c -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:27)
18 Charly Prod CI                 0x10013663c -[BroadcastDisplayerViewController dismissController] (BroadcastDisplayerViewController.m:351)
19 UIKit                          0x187dc6f80 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 64
20 UIKit                          0x187dca688 _UIGestureRecognizerSendTargetActions + 124
21 UIKit                          0x18799173c _UIGestureRecognizerSendActions + 260
22 UIKit                          0x1878300f0 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 764
23 UIKit                          0x187dba680 _UIGestureEnvironmentUpdate + 1100
24 UIKit                          0x187dba1e0 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 408
25 UIKit                          0x187db949c -[UIGestureEnvironment _updateGesturesForEvent:window:] + 268
26 UIKit                          0x18782e30c -[UIWindow sendEvent:] + 2960
27 UIKit                          0x1877feda0 -[UIApplication sendEvent:] + 340
28 UIKit                          0x187fe875c __dispatchPreprocessedEventFromEventQueue + 2736
29 UIKit                          0x187fe2130 __handleEventQueue + 784
30 CoreFoundation                 0x1818f6b5c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
31 CoreFoundation                 0x1818f64a4 __CFRunLoopDoSources0 + 524
32 CoreFoundation                 0x1818f40a4 __CFRunLoopRun + 804
33 CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
34 GraphicsServices               0x1832d6198 GSEventRunModal + 180
35 UIKit                          0x1878697fc -[UIApplication _run] + 684
36 UIKit                          0x187864534 UIApplicationMain + 208
37 Charly Prod CI                 0x1001a0ab8 main (main.m:14)
38 libdispatch.dylib              0x1808055b8 (Missing)

--

#0. Crashed: io.ably.main
0  libdispatch.dylib              0x1807e2f20 _dispatch_barrier_sync_f_slow + 596
1  Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
2  Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
3  Charly Prod CI                 0x100153a9c -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:27)
4  Charly Prod CI                 0x100134378 -[BroadcastDisplayerViewController garbageCollectAbly] (BroadcastDisplayerViewController.m:157)
5  Charly Prod CI                 0x1001342e8 -[BroadcastDisplayerViewController dealloc] (BroadcastDisplayerViewController.m:152)
6  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
7  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
8  libsystem_blocks.dylib         0x180827a28 _Block_release + 144
9  Foundation                     0x18236607c -[__NSObserver dealloc] + 128
10 Charly Prod CI                 0x1001f2644 -[ARTEventListener removeObserver] (ARTEventEmitter.m:88)
11 Charly Prod CI                 0x1001f41c8 -[ARTEventEmitter resetListeners] (ARTEventEmitter.m:245)
12 Charly Prod CI                 0x100214dd8 -[ARTRealtimeChannel _unsubscribe] (ARTRealtimeChannel.m:418)
13 Charly Prod CI                 0x100214ca0 __33-[ARTRealtimeChannel unsubscribe]_block_invoke (ARTRealtimeChannel.m:412)
14 libdispatch.dylib              0x1807d21bc _dispatch_client_callout + 16
15 libdispatch.dylib              0x1807df7f0 _dispatch_barrier_sync_f_invoke + 84
16 Charly Prod CI                 0x100214c1c -[ARTRealtimeChannel unsubscribe] (ARTRealtimeChannel.m:415)
17 Charly Prod CI                 0x100153a9c -[AblyManager unsubscribeFromChannelNamed:] (AblyManager.m:27)
18 Charly Prod CI                 0x10013663c -[BroadcastDisplayerViewController dismissController] (BroadcastDisplayerViewController.m:351)
19 UIKit                          0x187dc6f80 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 64
20 UIKit                          0x187dca688 _UIGestureRecognizerSendTargetActions + 124
21 UIKit                          0x18799173c _UIGestureRecognizerSendActions + 260
22 UIKit                          0x1878300f0 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 764
23 UIKit                          0x187dba680 _UIGestureEnvironmentUpdate + 1100
24 UIKit                          0x187dba1e0 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 408
25 UIKit                          0x187db949c -[UIGestureEnvironment _updateGesturesForEvent:window:] + 268
26 UIKit                          0x18782e30c -[UIWindow sendEvent:] + 2960
27 UIKit                          0x1877feda0 -[UIApplication sendEvent:] + 340
28 UIKit                          0x187fe875c __dispatchPreprocessedEventFromEventQueue + 2736
29 UIKit                          0x187fe2130 __handleEventQueue + 784
30 CoreFoundation                 0x1818f6b5c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
31 CoreFoundation                 0x1818f64a4 __CFRunLoopDoSources0 + 524
32 CoreFoundation                 0x1818f40a4 __CFRunLoopRun + 804
33 CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
34 GraphicsServices               0x1832d6198 GSEventRunModal + 180
35 UIKit                          0x1878697fc -[UIApplication _run] + 684
36 UIKit                          0x187864534 UIApplicationMain + 208
37 Charly Prod CI                 0x1001a0ab8 main (main.m:14)
38 libdispatch.dylib              0x1808055b8 (Missing)

#1. com.apple.uikit.eventfetch-thread
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  Foundation                     0x18235f26c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6  Foundation                     0x18237fdd0 -[NSRunLoop(NSRunLoop) runUntilDate:] + 96
7  UIKit                          0x1881ddc38 -[UIEventFetcher threadMain] + 136
8  Foundation                     0x18245ce68 __NSThread__start__ + 1024
9  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
10 libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
11 libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#2. com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  CFNetwork                      0x182027a70 +[NSURLConnection(Loader) _resourceLoadLoop:] + 336
6  Foundation                     0x18245ce68 __NSThread__start__ + 1024
7  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
8  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
9  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#3. com.twitter.crashlytics.ios.MachExceptionServer
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  Charly Prod CI                 0x1007c8c54 CLSMachExceptionServer + 488812
3  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
4  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
5  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#4. AFNetworking
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  Foundation                     0x18235f26c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6  Foundation                     0x1823b3aa0 -[NSRunLoop(NSRunLoop) run] + 88
7  Charly Prod CI                 0x1001c08b0 +[AFURLConnectionOperation networkRequestThreadEntryPoint:] (AFURLConnectionOperation.m:164)
8  Foundation                     0x18245ce68 __NSThread__start__ + 1024
9  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
10 libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
11 libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#5. AVAudioSession Notify Thread
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  AVFAudio                       0x19b4c3d24 GenericRunLoopThread::Entry(void*) + 164
6  AVFAudio                       0x19b4e9d9c CAPThread::Entry(CAPThread*) + 84
7  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
8  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
9  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#6. Thread
0  libsystem_kernel.dylib         0x180917314 __semwait_signal + 8
1  libsystem_c.dylib              0x18083525c nanosleep + 212
2  libsystem_c.dylib              0x18089f288 sleep + 44
3  Charly Prod CI                 0x1003e5ea4 monitorCachedData (KSCrashCachedData.c:148)
4  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
5  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
6  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#7. com.squareup.SocketRocket.NetworkThread
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  Foundation                     0x18235f26c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6  Charly Prod CI                 0x10051d7ec -[_SRRunLoopThread main] (SRWebSocket.m:1903)
7  Foundation                     0x18245ce68 __NSThread__start__ + 1024
8  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
9  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
10 libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#8. com.apple.CFSocket.private
0  libsystem_kernel.dylib         0x18091723c __select + 8
1  CoreFoundation                 0x1818fd468 __CFSocketManager + 640
2  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
3  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
4  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#9. com.apple.CoreMotion.MotionThread
0  libsystem_kernel.dylib         0x1808f9188 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1808f8ff8 mach_msg + 72
2  CoreFoundation                 0x1818f65d0 __CFRunLoopServiceMachPort + 192
3  CoreFoundation                 0x1818f41ec __CFRunLoopRun + 1132
4  CoreFoundation                 0x1818222b8 CFRunLoopRunSpecific + 444
5  CoreFoundation                 0x18186fb44 CFRunLoopRun + 112
6  CoreMotion                     0x1886e5120 (null) + 203196
7  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
8  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
9  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#10. Thread
0  libsystem_kernel.dylib         0x180916e1c __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x1809dc9c0 _pthread_cond_wait + 640
2  Charly Prod CI                 0x1008cda50 uv_cond_wait (thread.c:374)
3  Charly Prod CI                 0x1008c27b0 worker (threadpool.c:73)
4  Charly Prod CI                 0x1008cd680 uv__thread_start (thread.c:51)
5  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
6  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
7  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#11. Thread
0  libsystem_kernel.dylib         0x180916e1c __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x1809dc9c0 _pthread_cond_wait + 640
2  Charly Prod CI                 0x1008cda50 uv_cond_wait (thread.c:374)
3  Charly Prod CI                 0x1008c27b0 worker (threadpool.c:73)
4  Charly Prod CI                 0x1008cd680 uv__thread_start (thread.c:51)
5  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
6  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
7  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#12. Thread
0  libsystem_kernel.dylib         0x180916e1c __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x1809dc9c0 _pthread_cond_wait + 640
2  Charly Prod CI                 0x1008cda50 uv_cond_wait (thread.c:374)
3  Charly Prod CI                 0x1008c27b0 worker (threadpool.c:73)
4  Charly Prod CI                 0x1008cd680 uv__thread_start (thread.c:51)
5  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
6  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
7  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#13. Thread
0  libsystem_kernel.dylib         0x180916e1c __psynch_cvwait + 8
1  libsystem_pthread.dylib        0x1809dc9c0 _pthread_cond_wait + 640
2  Charly Prod CI                 0x1008cda50 uv_cond_wait (thread.c:374)
3  Charly Prod CI                 0x1008c27b0 worker (threadpool.c:73)
4  Charly Prod CI                 0x1008cd680 uv__thread_start (thread.c:51)
5  libsystem_pthread.dylib        0x1809dd850 _pthread_body + 240
6  libsystem_pthread.dylib        0x1809dd760 _pthread_body + 282
7  libsystem_pthread.dylib        0x1809dad94 thread_start + 4

#14. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db160 _pthread_wqthread + 968
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#15. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db160 _pthread_wqthread + 968
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#16. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db344 _pthread_wqthread + 1452
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#17. Thread
0  libsystem_pthread.dylib        0x1809dad88 start_wqthread + 126

#18. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db160 _pthread_wqthread + 968
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#19. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db344 _pthread_wqthread + 1452
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#20. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db160 _pthread_wqthread + 968
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

#21. Thread
0  libsystem_kernel.dylib         0x180917a88 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x1809db344 _pthread_wqthread + 1452
2  libsystem_pthread.dylib        0x1809dad8c start_wqthread + 4

@ricardopereira
Copy link
Contributor

@liuzhen2008 Thanks a lot!

But go back to my question - would you say it is safer if i always run subscribe/unsubcribe in main queue?

We changed the library to be thread safe so, but we might be missing some use cases.

If you don't mind. Could you explain the [BroadcastDisplayerViewController garbageCollectAbly] method? Thanks.

@liuzhen2008
Copy link
Author

liuzhen2008 commented Nov 9, 2017

@ricardopereira It was confusing naming on my part. It simply calls unsubscribe

- (void) garbageCollectAbly {
    [[AblyManager sharedInstance] unsubscribeFromChannelNamed:[self currentChannelName]];
}

@ricardopereira ricardopereira mentioned this issue Nov 9, 2017
@tcard
Copy link
Contributor

tcard commented Nov 9, 2017

This is a tricky one. Basically, we try to ensure that all user code (calls to callbacks, mainly) runs in a different queue (the main queue, by default) than our internal queue, io.ably.main. So before each call to a callback we do a dispatch_async to the main queue.

But in this case, the call to the user code happens because ARC deallocates an object when we remove the messages listener from the ARTEventEmitter, which happens to hold the last reference to such object, which causes its dealloc to be called, which in this case happens to call into Ably again, which dispatches again to the internal queue, which causes a deadlock since we're already in the internal queue.

So @ricardopereira ARTEventEmitter's removeListener must always dispatch its operations to the user's queue (ie. _userQueue throughout the codebase) so that this scenario is avoided. I believe that will fix this.

@tcard
Copy link
Contributor

tcard commented Nov 9, 2017

@ricardopereira Also, that dispatch inside removeListener might need to be an async one. I think so.

That will break a few tests, I expect.

@ricardopereira
Copy link
Contributor

@tcard Yes, that makes sense. Thanks.

@ricardopereira Also, that dispatch inside removeListener might need to be an async one. I think so.

You say so because the user queue can be the main queue, right?

@tcard
Copy link
Contributor

tcard commented Nov 10, 2017

@ricardopereira The user queue is the main queue by default. That ensures that user callbacks are run in the main thread, which is the only one that can do UI operations.

That's not the problem. The problem is that dispatch_sync can (and will, it able to) dispatch to the current thread, which can be the same thread the caller queue is running on. The only guarantee for a queue is that a dispatch on it will completely finish (ie. the block will return) before the next one is executed; but individual dispatches can be ran in any thread. dispatch_sync guarantees that by crashing if you attempt to dispatch to a queue that's already in the middle of a dispatch in the same thread, down the call stack, which is what's happening here.

dispatch_async doesn't need to crash to hold this guarantee, since it can just queue the operation to be dispatched later, when the current dispatch finishes.

@tcard
Copy link
Contributor

tcard commented Nov 30, 2017

@liuzhen2008 I just realized we didn't get back to you on this; sorry for that. This should have been fixed by a7b67c6. We're going to do a release soon including that and other fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working. It's clear that this does need to be fixed.
Development

No branches or pull requests

4 participants