Understanding CMIO Extension

Hello,

I am getting the following errors when building a Mac Camera Extension with web sockets. I am using URLSessionWebsocketTask as my web socket library. I built a test program for my code and in there I can see my web sockets are working properly, but when I run it from the System Extension I get the following errors. The socket opens for two - three messages then crashes. I couldnt find any documentation online for the following errors

CMIOExtensionProvider.m:1975:-[CMIOExtensionProvider removeProviderContext:]_block_invoke Unregistered provider context <CMIOExtensionProviderContext: ->, don't be surprised if things go badly

CMIOExtensionProviderContext.m:64:-[CMIOExtensionProviderContext initWithConnection:]_block_invoke [391] received Connection invalid``

The socket opens for two - three messages then crashes.

Those log messages don’t seem to have any relation to your networking code. Are you sure that these problems are correlated?

One option here would be to temporarily disable your WebSockets code. Does your extension still crash?

Also, when it crashes, does it generate a crash report? If so, please post it here. See Posting a Crash Report for instructions.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn!

Thanks for the response! I commented out the websocket code and I still see the same errors in the Console and the extension runs just fine so I guess we can't attribute my issues to those two messages (though I am still curious about what those messages mean). I have attached the crash report. My primary source of confusion here is why I have no issues with the websockets in my test app and why they cause problems in the system extension. In the app sandbox I have given my extension access to Incoming / Outcoming connections and I see my client (not shown) receiving a few messages before crashing. I have attached the crash report

I have attached the crash report.

Thanks.

Consider this:

Exception Type:                EXC_BREAKPOINT (SIGTRAP)

This almost always means you’ve hit a trap, that is, the process killed itself because of an assertion failure of some form, like accessing an element out of bounds in a Swift array.

Now look at the backtrace of the crashing thread:

Thread 6 Crashed::    Dispatch queue: com.apple.NSURLSession-delegate
0 libswiftCore.dylib … closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 380
1 libswiftCore.dylib … closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 380
2 libswiftCore.dylib … closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 200
3 libswiftCore.dylib … closure #1 in _assertionFailure(_:_:file:line:flags:) + 212
4 libswiftCore.dylib … _assertionFailure(_:_:file:line:flags:) + 236
5 AmazonChimeScience.… closure #1 in ExtensionStreamSource.captureOutput(_:didOutput:from:) + 5000 (ExtensionProvider.swift:400)
6 Foundation         … closure #1 in NSURLSessionWebSocketTask.receive(completionHandler:) + 284
7 Foundation         … thunk for @escaping @callee_guaranteed @Sendable (@guaranteed NSURLSessionWebSocketMessage?, @guaranteed Error?) -> () + 88
8 libdispatch.dylib  … _dispatch_call_block_and_release + 32
…

Frames 8 and up are all Dispatch boilerplate, indicating that frame 7 was run by a block on a queue. Frames 7 through 5 are your code. Frames 4 and up are all the Swift runtime. Frame 4 clearly indicates that your code in frame 5 has trapped because an assert failed. You need to uncover the identity of that code and find it what assert failed.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn!

I did some research on that error and I am thinking that the issue is related to how im using/ not using self through out my code.

This is how I create my web socket. I am a little confused what i should be using as the delegate and the delegate queue. The class I am working in right now inherits the URLSessionWebSocketDelegate.

    let urlString = "ws://localhost:8000"
    if let url = URL(string: urlString) {
      var request = URLRequest(url: url)
      let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main)
      webSocket = session.webSocketTask(with: request)
      webSocket!.resume()
    }

Here is my websocket send and receive. I am sending a video stream to a server and I want that stream back to replace the webcam stream. I marked the line in the code bellow that causes the exception in the crash report. The only difference between the testing app that works just fine and the extension that doesn't work is the single if deviceSource._isExtension

webSocket?.send(.string(stringData!), completionHandler: { [weak self] error in
      guard let weakself = self else {
        logger.error("error in setting weak self 1")
        return
      }
      if let error = error {
        print("Failed with Error \(error.localizedDescription)")
      } else {
        weakself.webSocket?.receive(completionHandler: { [weak self] result in
          guard let weakself = self else {
            logger.error("error in setting weak self 2")
            return
          }
          switch result {
          case .failure(let error):
            print(error.localizedDescription)
          case .success(let message):
            switch message {
            case .string(let base64Image):
              
             // Processing user input not shown


              var timimgInfo = CMSampleTimingInfo()
              var formatDescription: CMFormatDescription? = nil
              CMVideoFormatDescriptionCreateForImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer2!, formatDescriptionOut: &formatDescription)

              err = CMSampleBufferCreateReadyWithImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer2!, formatDescription: formatDescription!, sampleTiming: &timimgInfo, sampleBufferOut: &sampleBuffer2)

              if err == 0 {
                if deviceSource._isExtension { //Extension code
                  if let sb2 = sampleBuffer2 {
                    // this is the line that crashes according to the crash report (ExtensionProvider.swift:400)
                    weakself.stream.send(sampleBuffer2!, discontinuity: [], hostTimeInNanoseconds: UInt64(timimgInfo.presentationTimeStamp.seconds * Double(NSEC_PER_SEC)))
                  } else {
                    logger.error("sb2 is null")
                  }

                } else {
                  deviceSource.extensionDeviceSourceDelegate?.bufferReceived(sampleBuffer2!) // testing app works just fine 
                }
              } else {
                logger.error("Error in stream: \(err)")
              }
            case .data(let data):
              let base64Image = String(decoding: data, as: UTF8.self)

            default:
              print("Unknown type received from WebSocket")
            }
          }
        })
      }
    })```


Where is sampleBuffer2 stored? Is it a property on self?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Understanding CMIO Extension
 
 
Q