feat: always saving the debug info data (#2024)

This commit is contained in:
Erick
2024-05-07 10:00:29 -07:00
committed by GitHub
parent c22601e6c9
commit f46f7151d6
5 changed files with 168 additions and 10 deletions
@@ -92,9 +92,9 @@ If this option is not provided, the version number will be determined from the p
)
..addFlag(
'debug-linker',
negatable: false,
defaultsTo: true,
help: 'Collects linker diagnostic information to help troubleshoot low '
'link percentages.',
'link percentages. File is saved to build/$_linkDebugInfoFileName.',
);
}
@@ -378,8 +378,9 @@ Please re-run the release command for this version or create a new release.''');
'🟢 Track: ${lightCyan.wrap('Production')}',
if (percentLinked != null)
'''🔗 Running ${lightCyan.wrap('${percentLinked.toStringAsFixed(1)}%')} on CPU''',
if (results['debug-linker'] == true)
'''🔍 Debug Info: ${lightCyan.wrap(_debugInfoOutpath)}''',
if (results['debug-linker'] == true &&
(percentLinked != null && percentLinked < minLinkPercentage))
'''🔍 Debug Info: ${lightCyan.wrap(_debugInfoOutputPath)}''',
];
logger.info(
@@ -453,9 +454,10 @@ ${summary.join('\n')}
'out.vmcode',
);
String get _debugInfoOutpath => p.join(
static const _linkDebugInfoFileName = 'linker_diagnostic.zip';
String get _debugInfoOutputPath => p.join(
_buildDirectory,
'linker_diagnostic.zip',
_linkDebugInfoFileName,
);
String _readVersionFromPlist() {
@@ -527,7 +529,8 @@ ${summary.join('\n')}
required File releaseArtifact,
}) async {
final patch = File(_aotOutputPath);
final dumpDebugInfo = results['debug-linker'] == true;
final dumpDebugInfo = results['debug-linker'] == true &&
(await aotTools.isLinkDebugInfoSupported());
if (!patch.existsSync()) {
logger.err('Unable to find patch AOT file at ${patch.path}');
@@ -571,7 +574,7 @@ ${summary.join('\n')}
debugInfoZip.copySync(
p.join(
'build',
_debugInfoOutpath,
_debugInfoOutputPath,
),
);
}
@@ -131,6 +131,11 @@ class AotTools {
return tryParseVersion(version) ?? noVersion;
}
Future<bool> isLinkDebugInfoSupported() async {
final result = await _exec(['link', '--help']);
return result.stdout.toString().contains('dump-debug-info');
}
/// Generate a link vmcode file from two AOT snapshots.
Future<double?> link({
required String base,
+2 -2
View File
@@ -762,10 +762,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b"
url: "https://pub.dev"
source: hosted
version: "14.2.1"
version: "14.2.2"
watcher:
dependency: transitive
description:
@@ -18,6 +18,7 @@ import 'package:shorebird_cli/src/deployment_track.dart';
import 'package:shorebird_cli/src/doctor.dart';
import 'package:shorebird_cli/src/engine_config.dart';
import 'package:shorebird_cli/src/executables/aot_tools.dart';
import 'package:shorebird_cli/src/executables/executables.dart';
import 'package:shorebird_cli/src/executables/xcodebuild.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/os/operating_system_interface.dart';
@@ -529,6 +530,8 @@ flutter:
command = runWithOverrides(
() => PatchIosCommand(archiveDiffer: archiveDiffer),
)..testArgResults = argResults;
when(aotTools.isLinkDebugInfoSupported).thenAnswer((_) async => true);
});
test('supports alpha alias', () {
@@ -1321,6 +1324,67 @@ Please re-run the release command for this version or create a new release.'''),
).called(1);
},
);
test(
'prints the file location when linking is less than the minimum',
() async {
const notEnoughLinkPercentage = 60.0;
when(
() => aotTools.link(
base: any(named: 'base'),
patch: any(named: 'patch'),
analyzeSnapshot: any(named: 'analyzeSnapshot'),
genSnapshot: any(named: 'genSnapshot'),
kernel: any(named: 'kernel'),
workingDirectory: any(named: 'workingDirectory'),
outputPath: any(named: 'outputPath'),
dumpDebugInfoPath: any(named: 'dumpDebugInfoPath'),
),
).thenAnswer(
(_) async => notEnoughLinkPercentage,
);
when(() => argResults['debug-linker']).thenReturn(true);
setUpProjectRoot();
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, ExitCode.success.code);
final captured = verify(() => logger.info(captureAny())).captured
as List<Object?>;
final contains = captured.whereType<String>().any(
(element) => element.contains('Debug Info'),
);
expect(contains, isTrue);
},
);
group("when aot-tools don't support debugging the link command", () {
test(
"don't debug even when the flag is true",
() async {
when(() => argResults['debug-linker']).thenReturn(true);
when(aotTools.isLinkDebugInfoSupported).thenAnswer(
(_) async => false,
);
setUpProjectRoot();
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, ExitCode.success.code);
verify(
() => aotTools.link(
base: any(named: 'base'),
patch: any(named: 'patch'),
analyzeSnapshot: any(named: 'analyzeSnapshot'),
genSnapshot: any(named: 'genSnapshot'),
kernel: any(named: 'kernel'),
workingDirectory: any(named: 'workingDirectory'),
outputPath: any(named: 'outputPath'),
),
).called(1);
},
);
});
});
});
@@ -474,6 +474,92 @@ void main() {
).called(1);
});
});
group('isLinkDebugInfoSupported', () {
test('returns true when the argument is present in the help', () async {
final result = MockShorebirdProcessResult();
when(() => result.exitCode).thenReturn(ExitCode.success.code);
when(() => result.stdout).thenReturn('''
Link two aot snapshots.
Usage: aot_tools link [arguments]
-h, --help Print this usage information.
--base (mandatory) Path to the base snapshot to link against.
--patch (mandatory) Path to the patch snapshot to link.
--analyze-snapshot (mandatory) Path to analyze_snapshot binary.
--gen-snapshot (mandatory) Path to gen_snapshot binary.
--kernel (mandatory) Path to the patch kernel (.dill) file.
--output (mandatory) Path to the output vmcode file.
--enable-asserts Whether to enable asserts.
--linker-overrides Path to the linker overrides json file.
--dump-debug-info When specified, debug information will be generated and written to the provided path.
--reporter Set how to print link results.
[json] Prints the results in json format.
[pretty] (default) Prints the results in a human readable format.
--redirect-to Redirect output to a file.
Run "aot_tools help" to see global options.
''');
when(
() => process.run(
any(),
any(),
workingDirectory: any(named: 'workingDirectory'),
),
).thenAnswer((_) async => result);
await expectLater(
runWithOverrides(() => aotTools.isLinkDebugInfoSupported()),
completion(isTrue),
);
});
test(
'returns false when the argument is not present in the help',
() async {
final result = MockShorebirdProcessResult();
when(() => result.exitCode).thenReturn(ExitCode.success.code);
when(() => result.stdout).thenReturn('''
Link two aot snapshots.
Usage: aot_tools link [arguments]
-h, --help Print this usage information.
--base (mandatory) Path to the base snapshot to link against.
--patch (mandatory) Path to the patch snapshot to link.
--analyze-snapshot (mandatory) Path to analyze_snapshot binary.
--gen-snapshot (mandatory) Path to gen_snapshot binary.
--kernel (mandatory) Path to the patch kernel (.dill) file.
--output (mandatory) Path to the output vmcode file.
--enable-asserts Whether to enable asserts.
--linker-overrides Path to the linker overrides json file.
--reporter Set how to print link results.
[json] Prints the results in json format.
[pretty] (default) Prints the results in a human readable format.
--redirect-to Redirect output to a file.
Run "aot_tools help" to see global options.
''');
when(
() => process.run(
any(),
any(),
workingDirectory: any(named: 'workingDirectory'),
),
).thenAnswer((_) async => result);
await expectLater(
runWithOverrides(() => aotTools.isLinkDebugInfoSupported()),
completion(isFalse),
);
},
);
});
});
group('isGeneratePatchDiffBaseSupported', () {