From 35a077230ac4ca9d18c25954909a9b26f6b01ec7 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Sat, 10 Sep 2022 14:34:17 +0200 Subject: [PATCH] start/pause/stop: Readd 'generateHandler' helper This reintroduces code which was removed in 481c580c8d0. The Block_copy/Block_release calls from this helper seem to be needed on my x86_64 macOS11 machine. Without this, example/linux/virtualization segfaults in startWithCompletionHandler. This fixes this ASAN error: ================================================================= ==56003==ERROR: AddressSanitizer: requested allocation size 0x53cb4e83f8b48 (0x53cb4e83f9b48 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T6) #0 0x43f0400 in wrap_malloc+0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x44400) #1 0x7fff205753ba in _Block_copy+0x5e (libsystem_blocks.dylib:x86_64+0x13ba) #2 0x7fff6f594307 in Base::BlockPtr Base::BlockPtr::from_callable<-[VZVirtualMachine startWithCompletionHandler:]::$_13>(-[VZVirtualMachine startWithCompletionHandler:]::$_13)::'lambda'(void*, bool)::__invoke(void*, bool)+0xb37 (Virtualization:x86_64+0x24307) #3 0x43ef5fa in __wrap_dispatch_async_block_invoke+0xca (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x435fa) #4 0x7fff20691622 in _dispatch_call_block_and_release+0xb (libdispatch.dylib:x86_64+0x2622) #5 0x7fff20692805 in _dispatch_client_callout+0x7 (libdispatch.dylib:x86_64+0x3805) #6 0x7fff206985e9 in _dispatch_lane_serial_drain+0x25d (libdispatch.dylib:x86_64+0x95e9) #7 0x7fff206990ac in _dispatch_lane_invoke+0x16d (libdispatch.dylib:x86_64+0xa0ac) #8 0x7fff206a2c0c in _dispatch_workloop_worker_thread+0x32a (libdispatch.dylib:x86_64+0x13c0c) #9 0x7fff2083945c in _pthread_wqthread+0x139 (libsystem_pthread.dylib:x86_64+0x345c) #10 0x7fff2083842e in start_wqthread+0xe (libsystem_pthread.dylib:x86_64+0x242e) --- virtualization.m | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/virtualization.m b/virtualization.m index 682ef168..d85f9a2d 100644 --- a/virtualization.m +++ b/virtualization.m @@ -1005,47 +1005,60 @@ bool requestStopVirtualMachine(void *machine, void *queue, void **error) return queue; } +typedef void (^handler_t)(NSError *); + +handler_t generateHandler(void handler(void *, char *)) +{ + handler_t ret; + @autoreleasepool { + ret = Block_copy(^(NSError *err){ + virtualMachineCompletionHandler(handler, err); + }); + } + return ret; +} + void startWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + handler_t handler = generateHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine startWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine startWithCompletionHandler:handler]; }); + Block_release(handler); } } void pauseWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + handler_t handler = generateHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine pauseWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine pauseWithCompletionHandler:handler]; }); + Block_release(handler); } } void resumeWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + handler_t handler = generateHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine resumeWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine resumeWithCompletionHandler:handler]; }); + Block_release(handler); } } void stopWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 12, *)) { + handler_t handler = generateHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine stopWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine stopWithCompletionHandler:handler]; }); + Block_release(handler); } }