Skip to content

dbburgess/opentok-crash-test

Repository files navigation

OpenTok Crash Test

This repo demonstrates a crash in the OpenTok iOS SDK when using a custom OTVideoCapture for OTPublisherKit. This specifically applies to ARC-enabled projects (which Swift is automatically), but could also present issues in non-ARC projects.

Crash Details

Note: There is an update to these details, see additional details below.

When setting up OTPublisherKit to publish to an OTSession, if you provide your own OTVideoCapture object, there is a crash when everything is cleaned up and shut down. There is some interesting memory management issues going on here. If you just create the capture device and assign it like this:

func setupCapture() {
    let videoCapture = OpenTokVideoCapturer()
    publisher?.videoCapture = videoCapture
}

The videoCapture property on the publisher is actually deallocated immediately, once it is out of the current scope. So, when the publisher tries to do anything with the capture device, it causes a crash trying to reference a deallocated object. You can keep the capture object around, by using a property which holds a strong reference to it, like so:

var videoCapture: OpenTokVideoCapturer? = nil

func setupCapture() {
    videoCapture = OpenTokVideoCapturer()
    publisher?.videoCapture = videoCapture
}

And this will keep the capture device around for the publisher to use, and keeps it happy for a while. However, ARC magically releases videoCapture when the parent object is deallocated, and there is also a release somewhere in the publisher when it gets cleaned up as well, causing it to be over-released and a crash by trying to release a deallocated object, yet again.

Pretty much all of the sample code for doing this (including the sample code) that I've seen has been in Objective-C, presumably with ARC not enabled, looks something like this:

publisher.videoCapture = [[OpenTokVideoCapturer alloc] init];

...Which violates the Cocoa Memory Management Policy, because this should look like this:

publisher.videoCapture = [[[OpenTokVideoCapturer alloc] init] autorelease];

In summary, the SDK is over-releasing videoCapture, and it is just working okay because most code using it is based off of the sample code and happens to leak. So the SDK is accidentally plugging the leak...But this causes a crash on applications that manage memory correctly, or are using ARC.

Reproducing

  1. Clone this repo.
  2. Run pod install.
  3. Open the workspace and run.
  4. Tap the go button.
  5. Wait a few seconds for OpenTok to initialize and connect.
  6. Tap the back button on the top navigation bar.
  7. Observe the crash.

Workaround

For anyone using Swift, I've added an example of a simple hack to workaround this issue to the project. Simply uncomment TokViewController.swift#L77 to see it in action. All it is doing is performing a retain to +1 the reference count without a corresponding release, to match the behavior of the above sample Objective-C code. In any other circumstance, this would result in a memory leak...So be conscious of that if this bug gets fixed in a newer version of the SDK.

Additional Details

There is a fun discussion about this in the OpenTok Support Forums worth perusing. In short, the issue is actually that ARC sees the initCapture method on the class implementing OTVideoCapture as a initializer, and as such, is inserting a release without a corresponding retain. This is causing the reference count to get slightly out of whack, since it isn't actually an initializer.

I don't think this should actually be happening, because according to the ARC docs for what defines an init method, they must "must return an Objective-C pointer type", and the method certainly doesn't return one. However, Swift initializers do not return a value, which may be why ARC is treating the method this way.

Moral of the story: Don't use init in your method names, unless it is actually an initializer.

Test Version Details

These are the versions I used for my test, although other versions likely exhibit the same behavior.

  • iOS: v9.3
  • XCode: v7.3.1
  • OpenTok SDK: v2.8.1
  • CocoaPods: v1.0.0.rc.2

About

Demonstration of a crash using OpenTok.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published