@@ -288,6 +288,9 @@ class IOSDeployDebugger {
288288 bool get debuggerAttached => _debuggerState == _IOSDeployDebuggerState .attached;
289289 _IOSDeployDebuggerState _debuggerState;
290290
291+ @visibleForTesting
292+ String ? symbolsDirectoryPath;
293+
291294 // (lldb) platform select remote-'ios' --sysroot
292295 // https://github.com/ios-control/ios-deploy/blob/1.11.2-beta.1/src/ios-deploy/ios-deploy.m#L33
293296 // This regex is to get the configurable lldb prompt. By default this prompt will be "lldb".
@@ -306,6 +309,9 @@ class IOSDeployDebugger {
306309 // (lldb) Process 6152 resuming
307310 static final RegExp _lldbProcessResuming = RegExp (r'Process \d+ resuming' );
308311
312+ // Symbol Path: /Users/swarming/Library/Developer/Xcode/iOS DeviceSupport/16.2 (20C65) arm64e/Symbols
313+ static final RegExp _symbolsPathPattern = RegExp (r'.*Symbol Path: ' );
314+
309315 // Send signal to stop (pause) the app. Used before a backtrace dump.
310316 static const String _signalStop = 'process signal SIGSTOP' ;
311317
@@ -362,12 +368,25 @@ class IOSDeployDebugger {
362368 return ;
363369 }
364370
371+ // Symbol Path: /Users/swarming/Library/Developer/Xcode/iOS DeviceSupport/16.2 (20C65) arm64e/Symbols
372+ if (_symbolsPathPattern.hasMatch (line)) {
373+ _logger.printTrace ('Detected path to iOS debug symbols: "$line "' );
374+ final String prefix = _symbolsPathPattern.stringMatch (line) ?? '' ;
375+ if (prefix.isEmpty) {
376+ return ;
377+ }
378+ symbolsDirectoryPath = line.substring (prefix.length);
379+ return ;
380+ }
381+
365382 // (lldb) run
366383 // success
367384 // 2020-09-15 13:42:25.185474-0700 Runner[477:181141] flutter: The Dart VM service is listening on http://127.0.0.1:57782/
368385 if (lldbRun.hasMatch (line)) {
369386 _logger.printTrace (line);
370387 _debuggerState = _IOSDeployDebuggerState .launching;
388+ // TODO(vashworth): Remove all debugger state comments when https://github.com/flutter/flutter/issues/126412 is resolved.
389+ _logger.printTrace ('Debugger state set to launching.' );
371390 return ;
372391 }
373392 // Next line after "run" must be "success", or the attach failed.
@@ -376,6 +395,7 @@ class IOSDeployDebugger {
376395 _logger.printTrace (line);
377396 final bool attachSuccess = line == 'success' ;
378397 _debuggerState = attachSuccess ? _IOSDeployDebuggerState .attached : _IOSDeployDebuggerState .detached;
398+ _logger.printTrace ('Debugger state set to ${attachSuccess ? 'attached' : 'detached' }.' );
379399 if (! debuggerCompleter.isCompleted) {
380400 debuggerCompleter.complete (attachSuccess);
381401 }
@@ -392,6 +412,7 @@ class IOSDeployDebugger {
392412 // Even though we're not "detached", just stopped, mark as detached so the backtrace
393413 // is only show in verbose.
394414 _debuggerState = _IOSDeployDebuggerState .detached;
415+ _logger.printTrace ('Debugger state set to detached.' );
395416
396417 // If we paused the app and are waiting to resume it, complete the completer
397418 final Completer <void >? processResumeCompleter = _processResumeCompleter;
@@ -422,6 +443,7 @@ class IOSDeployDebugger {
422443 if (_lldbProcessDetached.hasMatch (line)) {
423444 // The debugger has detached from the app, and there will be no more debugging messages.
424445 // Kill the ios-deploy process.
446+ _logger.printTrace (line);
425447 exit ();
426448 return ;
427449 }
@@ -430,6 +452,7 @@ class IOSDeployDebugger {
430452 _logger.printTrace (line);
431453 // we marked this detached when we received [_backTraceAll]
432454 _debuggerState = _IOSDeployDebuggerState .attached;
455+ _logger.printTrace ('Debugger state set to attached.' );
433456 return ;
434457 }
435458
@@ -510,6 +533,33 @@ class IOSDeployDebugger {
510533 _iosDeployProcess? .stdin.writeln (_processResume);
511534 }
512535
536+ /// Check what files are found in the device's iOS DeviceSupport directory.
537+ ///
538+ /// Expected files include Symbols (directory), Info.plist, and .finalized.
539+ ///
540+ /// If any of the expected files are missing or there are additional files
541+ /// (such as .copying_lock or .processing_lock), this may indicate the
542+ /// symbols may still be fetching or something went wrong when fetching them.
543+ ///
544+ /// Used for debugging test flakes: https://github.com/flutter/flutter/issues/121231
545+ Future <void > checkForSymbolsFiles (FileSystem fileSystem) async {
546+ if (symbolsDirectoryPath == null ) {
547+ _logger.printTrace ('No path provided for Symbols directory.' );
548+ return ;
549+ }
550+ final Directory symbolsDirectory = fileSystem.directory (symbolsDirectoryPath);
551+ if (! symbolsDirectory.existsSync ()) {
552+ _logger.printTrace ('Unable to find Symbols directory at $symbolsDirectoryPath ' );
553+ return ;
554+ }
555+ final Directory currentDeviceSupportDir = symbolsDirectory.parent;
556+ final List <FileSystemEntity > symbolStatusFiles = currentDeviceSupportDir.listSync ();
557+ _logger.printTrace ('Symbol files:' );
558+ for (final FileSystemEntity file in symbolStatusFiles) {
559+ _logger.printTrace (' ${file .basename }' );
560+ }
561+ }
562+
513563 Future <void > stopAndDumpBacktrace () async {
514564 if (! debuggerAttached) {
515565 return ;
0 commit comments