瀏覽代碼

vm(qemu): improve debug logging by adding more sources

osy 2 年之前
父節點
當前提交
95ba69576d

+ 1 - 2
Services/UTMLogging.m

@@ -23,9 +23,8 @@ void UTMLog(NSString *format, ...) {
     va_list args;
     va_start(args, format);
     NSString *line = [[NSString alloc] initWithFormat:[format stringByAppendingString:@"\n"] arguments:args];
-    [[UTMLogging sharedInstance] writeLine:line];
     va_end(args);
-    NSLog(@"%@", line);
+    [[UTMLogging sharedInstance] writeLine:line];
 }
 
 @implementation UTMLogging

+ 0 - 5
Services/UTMProcess.m

@@ -160,10 +160,6 @@ static int defaultEntry(UTMProcess *self, int argc, const char *argv[], const ch
     [_argv removeAllObjects];
 }
 
-- (void)printArgv {
-    UTMLog(@"Running: %@", self.arguments);
-}
-
 - (BOOL)didLoadDylib:(void *)handle {
     return YES;
 }
@@ -255,7 +251,6 @@ static int defaultEntry(UTMProcess *self, int argc, const char *argv[], const ch
 }
 
 - (void)startProcess:(nonnull NSString *)name completion:(nonnull void (^)(NSError * _Nullable))completion {
-    [self printArgv];
 #if TARGET_OS_IPHONE
     NSString *base = @"";
 #else

+ 1 - 0
Services/UTMQemuSystem.h

@@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
 @property (nonatomic) UTMQEMURendererBackend rendererBackend;
 @property (nonatomic, weak) id<QEMULauncherDelegate> launcherDelegate;
 @property (nonatomic, nullable) QEMULogging *logging;
+@property (nonatomic) BOOL hasDebugLog;
 
 - (instancetype)init NS_UNAVAILABLE;
 - (instancetype)initWithArguments:(NSArray<NSString *> *)arguments NS_UNAVAILABLE;

+ 12 - 1
Services/UTMQemuSystem.m

@@ -21,6 +21,7 @@
 @interface UTMQemuSystem ()
 
 @property (nonatomic) NSString *architecture;
+@property (nonatomic) NSMutableDictionary<NSString *, NSString *> *mutableEnvironment;
 
 @end
 
@@ -45,11 +46,12 @@ static int startQemu(UTMProcess *process, int argc, const char *argv[], const ch
     _rendererBackend = rendererBackend;
     switch (rendererBackend) {
         case kQEMURendererBackendAngleMetal:
-            self.environment = @{@"ANGLE_DEFAULT_PLATFORM": @"metal"};
+            self.mutableEnvironment[@"ANGLE_DEFAULT_PLATFORM"] = @"metal";
             break;
         case kQEMURendererBackendDefault:
         case kQEMURendererBackendAngleGL:
         default:
+            [self.mutableEnvironment removeObjectForKey:@"ANGLE_DEFAULT_PLATFORM"];
             break;
     }
 }
@@ -75,11 +77,20 @@ static int startQemu(UTMProcess *process, int argc, const char *argv[], const ch
     [logging writeLine:[NSString stringWithFormat:@"Launching: qemu-system-%@%@\n", self.architecture, self.arguments]];
 }
 
+- (void)setHasDebugLog:(BOOL)hasDebugLog {
+    _hasDebugLog = hasDebugLog;
+}
+
+- (NSDictionary<NSString *,NSString *> *)environment {
+    return self.mutableEnvironment;
+}
+
 - (instancetype)initWithArguments:(NSArray<NSString *> *)arguments architecture:(nonnull NSString *)architecture {
     self = [super initWithArguments:arguments];
     if (self) {
         self.entry = startQemu;
         self.architecture = architecture;
+        self.mutableEnvironment = [NSMutableDictionary dictionary];
     }
     return self;
 }

+ 9 - 1
Services/UTMQemuVirtualMachine.swift

@@ -243,8 +243,9 @@ extension UTMQemuVirtualMachine {
         guard await isSupported else {
             throw UTMQemuVirtualMachineError.emulationNotSupported
         }
+        let hasDebugLog = await config.qemu.hasDebugLog
         // start logging
-        if await config.qemu.hasDebugLog, let debugLogURL = await config.qemu.debugLogURL {
+        if hasDebugLog, let debugLogURL = await config.qemu.debugLogURL {
             await qemuVM.setRedirectLog(url: debugLogURL)
         } else {
             await qemuVM.setRedirectLog(url: nil)
@@ -274,6 +275,7 @@ extension UTMQemuVirtualMachine {
         system.currentDirectoryUrl = await config.socketURL
         system.remoteBookmarks = remoteBookmarks as NSDictionary
         system.rendererBackend = rendererBackend
+        system.hasDebugLog = hasDebugLog
         try Task.checkCancellation()
         
         if isShortcut {
@@ -291,8 +293,14 @@ extension UTMQemuVirtualMachine {
         if await config.sharing.isDirectoryShareReadOnly {
             options.insert(.isShareReadOnly)
         }
+        if hasDebugLog {
+            options.insert(.hasDebugLog)
+        }
         let spiceSocketUrl = await config.spiceSocketURL
         let ioService = UTMSpiceIO(socketUrl: spiceSocketUrl, options: options)
+        ioService.logHandler = { [weak system] (line: String) -> Void in
+            system?.logging?.writeLine(line)
+        }
         try ioService.start()
         try Task.checkCancellation()
         

+ 2 - 0
Services/UTMSpiceIO.h

@@ -29,6 +29,7 @@ typedef NS_OPTIONS(NSUInteger, UTMSpiceIOOptions) {
     UTMSpiceIOOptionsHasAudio             = (1 << 0),
     UTMSpiceIOOptionsHasClipboardSharing  = (1 << 1),
     UTMSpiceIOOptionsIsShareReadOnly      = (1 << 2),
+    UTMSpiceIOOptionsHasDebugLog          = (1 << 3),
 };
 
 NS_ASSUME_NONNULL_BEGIN
@@ -45,6 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
 #endif
 @property (nonatomic, weak, nullable) id<UTMSpiceIODelegate> delegate;
 @property (nonatomic, readonly) BOOL isConnected;
+@property (nonatomic, nullable) LogHandler_t logHandler;
 
 - (instancetype)init NS_UNAVAILABLE;
 - (instancetype)initWithSocketUrl:(NSURL *)socketUrl options:(UTMSpiceIOOptions)options NS_DESIGNATED_INITIALIZER;

+ 11 - 3
Services/UTMSpiceIO.m

@@ -53,6 +53,14 @@ NSString *const kUTMErrorDomain = @"com.utmapp.utm";
     return self.mutableSerials;
 }
 
+- (LogHandler_t)logHandler {
+    return CSMain.sharedInstance.logHandler;
+}
+
+- (void)setLogHandler:(LogHandler_t)logHandler {
+    CSMain.sharedInstance.logHandler = logHandler;
+}
+
 - (instancetype)initWithSocketUrl:(NSURL *)socketUrl options:(UTMSpiceIOOptions)options {
     if (self = [super init]) {
         self.socketUrl = socketUrl;
@@ -81,9 +89,9 @@ NSString *const kUTMErrorDomain = @"com.utmapp.utm";
     if (!self.spice) {
         self.spice = [CSMain sharedInstance];
     }
-#ifdef SPICE_DEBUG_LOGGING
-    [self.spice spiceSetDebug:YES];
-#endif
+    if ((self.options & UTMSpiceIOOptionsHasDebugLog) == UTMSpiceIOOptionsHasDebugLog) {
+        [self.spice spiceSetDebug:YES];
+    }
     // do not need to encode/decode audio locally
     g_setenv("SPICE_DISABLE_OPUS", "1", TRUE);
     // need to chdir to workaround AF_UNIX sun_len limitations

+ 2 - 2
UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -15,7 +15,7 @@
       "location" : "https://github.com/utmapp/CocoaSpice.git",
       "state" : {
         "branch" : "main",
-        "revision" : "4a35375f2bd3c3e9815e616e31a8b56bbcb79f08"
+        "revision" : "e0333efed6e9a9dd484e4901f05ffe8aff51f127"
       }
     },
     {
@@ -42,7 +42,7 @@
       "location" : "https://github.com/utmapp/QEMUKit.git",
       "state" : {
         "branch" : "main",
-        "revision" : "d979cb5249f34e18de07e82496a004f8ff3bbd0e"
+        "revision" : "c4a333e382fc7b182a40baa6a28d701d66bbc37e"
       }
     },
     {