From a16c4a9fe22a5e0aec30e4a02e9ee98c026bbc5d Mon Sep 17 00:00:00 2001 From: ZC Date: Mon, 29 Jun 2026 20:22:16 +0800 Subject: [PATCH] Merge pull request #29359 from zcinclude:fix/avfoundation-videowriter-destructor-sigsegv videoio(avfoundation): fix SIGSEGV crash when releasing VideoWriter on iOS #29359 Replace deprecated synchronous finishWriting with finishWritingWithCompletionHandler + dispatch_semaphore to properly wait for the async completion handler. The synchronous finishWriting method is deprecated since iOS 6 and, despite blocking until writing status completes, does NOT wait for internal NSOperation KVO observer blocks that are dispatched asynchronously to GCD worker threads. When the destructor returns and drains the autorelease pool, these blocks may access already-released objects, causing SIGSEGV. This fix uses a semaphore to block until the finishWritingWithCompletionHandler callback has fully completed, eliminating the race condition between the async block and autorelease pool drain. Fixes #28165 --- modules/videoio/src/cap_avfoundation_mac.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/videoio/src/cap_avfoundation_mac.mm b/modules/videoio/src/cap_avfoundation_mac.mm index 3bcd0928de..2e438360d3 100644 --- a/modules/videoio/src/cap_avfoundation_mac.mm +++ b/modules/videoio/src/cap_avfoundation_mac.mm @@ -1211,7 +1211,21 @@ CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() { if (mMovieWriterInput && mMovieWriter && mMovieWriterAdaptor) { [mMovieWriterInput markAsFinished]; - [mMovieWriter finishWriting]; + + // Use finishWritingWithCompletionHandler + semaphore to synchronously + // wait for the async completion block to finish, avoiding a race + // condition where NSOperation KVO observer blocks are dispatched + // asynchronously to GCD worker threads and may access already-released + // objects after the autorelease pool is drained. + // Replaces deprecated finishWriting (sync) which falsely appears safe + // but does NOT wait for internal NSOperation KVO callbacks to complete. + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + [mMovieWriter finishWritingWithCompletionHandler:^{ + dispatch_semaphore_signal(sem); + }]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + dispatch_release(sem); + [mMovieWriter release]; [mMovieWriterInput release]; [mMovieWriterAdaptor release];