Error opening subprocess with fork() and AVCaptureSession

Hi!

I am making an app that records the screen and microphone in MacOS, I specifically need it to run in a subprocess, for this I use fork(); The truth is that it marks the following error in loop:

Error:

CMIOHardware.cpp:379:CMIOObjectGetPropertyData Error: 2003332927, failed

2022-03-01 20:19:41.708913+0100 WebCamProj[8051:91700] [] CMIO_Unit_Convertor_VideoToolboxCompressor.cpp:461:rebuildVideoCompressor ### Err -12903

2022-03-01 20:19:41.709213+0100 WebCamProj[8051:91700] [] CMIO_Unit_Convertor_VideoToolboxCompressor.cpp:1958:doCompressBuffer [0x15382da00] EXCEPTION ON ERROR -12903

The example on which I base is the following, it comes from Apple's official website for developers:

https://developer.apple.com/library/archive/qa/qa1740/_index.html

The fragment that executes the operation looks something like this:

pid_t pidScreenRecorder;

if ((pidScreenRecorder = fork()) == 0) {

NSURL *pathUrl = [[NSURL alloc] initFileURLWithPath:[NSString stringWithFormat:@"%@%s", NSHomeDirectory(), "/myScreen.mov"]];

ScreenRecord *screenRec = [[ScreenRecord alloc] init];

[screenRec startScreenRecording:pathUrl];

  }

I do not know why this error occurs only with this API, I have used others, for example AVAudioRecorder individually and I have not had any problem.

Thanks you.

Hmmm, it seems that you’re calling fork without calling exec*. Is that right?

If so, that’s not supported on macOS [1]. Many Apple frameworks use Mach messaging [2] to communicate with helper processes, for example, launchd daemons and agents. Mach messaging and fork don’t play well together. The child inherits the parent’s memory but it does not inherit the parent’s Mach port namespace [3]. So the child thinks it has access to a bunch of Mach services but it doesn’t. This ends badly.

Many of the most-commonly used frameworks, like Foundation, have asserts that detect this situation and crash. It seems that AVFoundation doesn’t, and so you get undefined behaviour.

In short, if you call fork without calling exec* you will run into weird problems. If you’re porting Unix-y code that relies on this then you may get away with this, but not if you use any of Apple’s frameworks.

What’s you’re goal in spinning up a new process for this screen recording work? Most folks use threads for this sort thing.

Share and Enjoy

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

[1] It’s not supported on any Apple platform, but the iOS-based platforms don’t let you get this far because the sandbox blocks fork.

[2] Or technologies layered on top of that, most notably XPC.

[3] Except for certain special ports, most critically the bootstrap port.

Error opening subprocess with fork() and AVCaptureSession
 
 
Q