From c06169dcc2445bae7f323f1e3449de7b69aea4c2 Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 14 Oct 2022 12:06:28 +0900 Subject: [PATCH 1/4] added macOS 11 CI env --- .github/workflows/compile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 5a0ddfb..24b6013 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -27,6 +27,7 @@ jobs: fail-fast: false matrix: os: + - macOS-11 - macOS-12 go: - 1.17 From 3d5dae475583be1119d3c6c1e043e55fca60587a Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 14 Oct 2022 12:09:50 +0900 Subject: [PATCH 2/4] renamed virtualization_raise.h to virtualization_helper.h --- virtualization.h | 1 - virtualization.m | 1 + virtualization_arm64.m | 2 +- virtualization_debug.m | 2 +- virtualization_raise.h => virtualization_helper.h | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename virtualization_raise.h => virtualization_helper.h (100%) diff --git a/virtualization.h b/virtualization.h index 04bad6a..d44ce35 100644 --- a/virtualization.h +++ b/virtualization.h @@ -6,7 +6,6 @@ #pragma once -#import "virtualization_raise.h" #import #import diff --git a/virtualization.m b/virtualization.m index 63fc5ef..e13cd91 100644 --- a/virtualization.m +++ b/virtualization.m @@ -6,6 +6,7 @@ #import "virtualization.h" #import "virtualization_view.h" +#import "virtualization_helper.h" char *copyCString(NSString *nss) { diff --git a/virtualization_arm64.m b/virtualization_arm64.m index d7860b9..73d5982 100644 --- a/virtualization_arm64.m +++ b/virtualization_arm64.m @@ -1,6 +1,6 @@ #ifdef __arm64__ #import "virtualization_arm64.h" -#import "virtualization_raise.h" +#import "virtualization_helper.h" @implementation ProgressObserver - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; diff --git a/virtualization_debug.m b/virtualization_debug.m index 06fc86b..67fe356 100644 --- a/virtualization_debug.m +++ b/virtualization_debug.m @@ -5,7 +5,7 @@ // #import "virtualization_debug.h" -#import "virtualization_raise.h" +#import "virtualization_helper.h" /*! @abstract Create a VZGDBDebugStubConfiguration with debug port for GDB server. diff --git a/virtualization_raise.h b/virtualization_helper.h similarity index 100% rename from virtualization_raise.h rename to virtualization_helper.h From d532380f0f8a9307781ffb75c061d9ec40ccd029 Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 14 Oct 2022 12:34:07 +0900 Subject: [PATCH 3/4] readded helper to make a completion handler for VM With this fix, the completion handler is not processed on the stack, but once moved to the heap area and processed on it. In this way, we can treat parameters of the completion handler in Go (C) world. --- virtualization.m | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/virtualization.m b/virtualization.m index e13cd91..61e477c 100644 --- a/virtualization.m +++ b/virtualization.m @@ -5,8 +5,8 @@ // #import "virtualization.h" -#import "virtualization_view.h" #import "virtualization_helper.h" +#import "virtualization_view.h" char *copyCString(NSString *nss) { @@ -1060,14 +1060,23 @@ bool requestStopVirtualMachine(void *machine, void *queue, void **error) return queue; } +typedef void (^vm_completion_handler_t)(NSError *); + +vm_completion_handler_t makeVMCompletionHandler(const void *completionHandler) +{ + return Block_copy(^(NSError *err) { + virtualMachineCompletionHandler(handler, err); + }) +} + void startWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine startWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine startWithCompletionHandler:handler]; }); + Block_release(handler); return; } @@ -1077,11 +1086,11 @@ void startWithCompletionHandler(void *machine, void *queue, void *completionHand void pauseWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine pauseWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine pauseWithCompletionHandler:handler]; }); + Block_release(handler); return; } @@ -1091,11 +1100,11 @@ void pauseWithCompletionHandler(void *machine, void *queue, void *completionHand void resumeWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine resumeWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine resumeWithCompletionHandler:handler]; }); + Block_release(handler); return; } @@ -1105,11 +1114,11 @@ void resumeWithCompletionHandler(void *machine, void *queue, void *completionHan void stopWithCompletionHandler(void *machine, void *queue, void *completionHandler) { if (@available(macOS 12, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine stopWithCompletionHandler:^(NSError *err) { - virtualMachineCompletionHandler(completionHandler, err); - }]; + [(VZVirtualMachine *)machine stopWithCompletionHandler:handler]; }); + Block_release(handler); return; } From 0cb18dfdfaff381ac57c1d66be41c9a2040644ea Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 14 Oct 2022 12:54:43 +0900 Subject: [PATCH 4/4] added tests to check segmentation fault --- error_test.go | 12 --------- issues_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ virtualization.m | 6 ++--- 3 files changed, 66 insertions(+), 15 deletions(-) delete mode 100644 error_test.go create mode 100644 issues_test.go diff --git a/error_test.go b/error_test.go deleted file mode 100644 index 95369cf..0000000 --- a/error_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package vz - -import ( - "testing" -) - -func TestNonExistingFileSerialPortAttachment(t *testing.T) { - _, err := NewFileSerialPortAttachment("/non/existing/path", false) - if err == nil { - t.Error("NewFileSerialPortAttachment should have returned an error") - } -} diff --git a/issues_test.go b/issues_test.go new file mode 100644 index 0000000..b36ba18 --- /dev/null +++ b/issues_test.go @@ -0,0 +1,63 @@ +package vz + +import ( + "os" + "testing" +) + +func TestIssue50(t *testing.T) { + f, err := os.CreateTemp("", "vmlinuz") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + bootloader, err := NewLinuxBootLoader(f.Name()) + if err != nil { + t.Fatal(err) + } + config, err := NewVirtualMachineConfiguration(bootloader, 1, 1024*1024*1024) + if err != nil { + t.Fatal(err) + } + ok, err := config.Validate() + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("failed to validate config") + } + m, err := NewVirtualMachine(config) + if err != nil { + t.Fatal(err) + } + + t.Run("check for segmentation faults", func(t *testing.T) { + cases := map[string]func(){ + "start handler": func() { + m.Start(func(err error) { _ = err == nil }) + }, + "pause handler": func() { + m.Pause(func(err error) { _ = err == nil }) + }, + "resume handler": func() { + m.Resume(func(err error) { _ = err == nil }) + }, + "stop handler": func() { + m.Stop(func(err error) { _ = err == nil }) + }, + } + for name, run := range cases { + t.Run(name, func(t *testing.T) { + run() + }) + } + }) +} + +func TestIssue71(t *testing.T) { + _, err := NewFileSerialPortAttachment("/non/existing/path", false) + if err == nil { + t.Error("NewFileSerialPortAttachment should have returned an error") + } +} diff --git a/virtualization.m b/virtualization.m index 61e477c..4eedef3 100644 --- a/virtualization.m +++ b/virtualization.m @@ -1062,11 +1062,11 @@ bool requestStopVirtualMachine(void *machine, void *queue, void **error) typedef void (^vm_completion_handler_t)(NSError *); -vm_completion_handler_t makeVMCompletionHandler(const void *completionHandler) +vm_completion_handler_t makeVMCompletionHandler(void *completionHandler) { return Block_copy(^(NSError *err) { - virtualMachineCompletionHandler(handler, err); - }) + virtualMachineCompletionHandler(completionHandler, err); + }); } void startWithCompletionHandler(void *machine, void *queue, void *completionHandler)