-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support symbolicating native call stacks with --split-debug-info #43612
Comments
/cc @sstrickl |
So the separate debugging information (which is in ELF format) contains both the symbols and the DWARF information to symbolicate non-symbolic Dart stack traces. Currently, one way to do so is to use pkg/native_stack_traces. However, I'm not sure if an easy way to convert ELF files containing static symbol tables and DWARF information to a dSym file (which I'm guessing is the Mach-O equivalent of having a separate file with just debugging information similar to our ELF one) already exists. I'll look into this. (I'd be happy to just make a Mach-O output instead, but it seems like documentation of the Mach-O format was pulled at some point, so I'm not sure how stable it is outside of "what XCode produces" nowadays.) |
@sstrickl are you saying that you're generating ELF containers even for iOS / macOS builds? File formats like MachO and ELF are usually meant to be platform-dependent, so I'm not sure if it makes sense to even convert an ELF file into a MachO file. Many debuggers and symbolizers, including Usually, on iOS builds you would output the entire debugging information into the Another important point is to create a Edit: I just had a look at an iOS build and it is indeed emitting ELF for iOS builds. It would definitely be better to follow the above approach, since that allows tools like XCode to use the debug information. The standard command line utilities for Darwin development by Apple are not able to process ELF. |
Hi is there any updates? I want to obfuscate my flutter code in release build, and I definitely want to see error stack trace |
We are not actively working on this at the moment, because high priority uses cases are all covered to the best of our knowledge.
You can still manually symbolicate and deobfuscate your crashes, we emit enough information for you to do it. |
I just want to follow up on this given that @bruno-garcia indicated on getsentry/sentry-dart#444 that this is an important issue for Sentry team to resolve. To the best of my knowledge you have all necessary pieces to make this work, though it would require some changes to the Flutter CLI. We generate Mach-O through XCode toolchain, so I suggest we go the same route for Here is quick and dirty prototype, which would produce necessary diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart
index 74e40a37a9..7c9c5285ce 100644
--- a/packages/flutter_tools/lib/src/base/build.dart
+++ b/packages/flutter_tools/lib/src/base/build.dart
@@ -138,9 +138,15 @@ class AOTSnapshotter {
'--deterministic',
];
- // We strip snapshot by default, but allow to suppress this behavior
- // by supplying --no-strip in extraGenSnapshotOptions.
- bool shouldStrip = true;
+ final bool targetingApplePlatform =
+ platform == TargetPlatform.ios || platform == TargetPlatform.darwin_x64;
+ _logger.printTrace("targetingApplePlatform = ${targetingApplePlatform}");
+ final bool shouldSplitDebugInfo = splitDebugInfo?.isNotEmpty ?? false;
+
+ // We strip snapshot by default unless we need to split a dSYM out, but
+ // we allow to suppress stripping by supplying --no-strip in
+ // extraGenSnapshotOptions.
+ bool shouldStrip = !(targetingApplePlatform && shouldSplitDebugInfo);
if (extraGenSnapshotOptions != null && extraGenSnapshotOptions.isNotEmpty) {
_logger.printTrace('Extra gen_snapshot options: $extraGenSnapshotOptions');
@@ -186,7 +192,6 @@ class AOTSnapshotter {
// multiple debug files.
final String archName = getNameForTargetPlatform(platform, darwinArch: darwinArch);
final String debugFilename = 'app.$archName.symbols';
- final bool shouldSplitDebugInfo = splitDebugInfo?.isNotEmpty ?? false;
if (shouldSplitDebugInfo) {
_fileSystem.directory(splitDebugInfo)
.createSync(recursive: true);
@@ -197,7 +202,11 @@ class AOTSnapshotter {
// Faster async/await
if (shouldSplitDebugInfo) ...<String>[
'--dwarf-stack-traces',
- '--save-debugging-info=${_fileSystem.path.join(splitDebugInfo, debugFilename)}'
+ // --save-debugging-info produces non-native symbol format.
+ // NOTE: this will break `flutter symbolize` so it needs to be changed
+ // to use `atos`.
+ if (!targetingApplePlatform)
+ '--save-debugging-info=${_fileSystem.path.join(splitDebugInfo, debugFilename)}'
],
if (dartObfuscation)
'--obfuscate',
@@ -218,7 +227,7 @@ class AOTSnapshotter {
// On iOS and macOS, we use Xcode to compile the snapshot into a dynamic library that the
// end-developer can link into their app.
- if (platform == TargetPlatform.ios || platform == TargetPlatform.darwin_x64) {
+ if (targetingApplePlatform) {
final RunResult result = await _buildFramework(
appleArch: darwinArch,
isIOS: platform == TargetPlatform.ios,
@@ -227,6 +236,7 @@ class AOTSnapshotter {
outputPath: outputDir.path,
bitcode: bitcode,
quiet: quiet,
+ splitDebugInfo: shouldSplitDebugInfo ? splitDebugInfo : null,
);
if (result.exitCode != 0) {
return result.exitCode;
@@ -244,7 +254,8 @@ class AOTSnapshotter {
@required String assemblyPath,
@required String outputPath,
@required bool bitcode,
- @required bool quiet
+ @required bool quiet,
+ @required String splitDebugInfo,
}) async {
final String targetArch = getNameForDarwinArch(appleArch);
if (!quiet) {
@@ -298,8 +309,17 @@ class AOTSnapshotter {
final RunResult linkResult = await _xcode.clang(linkArgs);
if (linkResult.exitCode != 0) {
_logger.printError('Failed to link AOT snapshot. Linker terminated with exit code ${compileResult.exitCode}');
+ return linkResult;
+ }
+ if (splitDebugInfo == null) {
+ return linkResult;
+ }
+ final String dSYMPath = _fileSystem.path.join(splitDebugInfo, targetArch, 'App.dSYM');
+ final RunResult dsymutilResult = await _xcode.dsymutil(['-o', dSYMPath, appLib]);
+ if (dsymutilResult.exitCode != 0) {
+ _logger.printError('Failed to generate dSYM. dsymutil terminated with exit code ${compileResult.exitCode}');
}
- return linkResult;
+ return dsymutilResult;
}
bool _isValidAotPlatform(TargetPlatform platform, BuildMode buildMode) {
diff --git a/packages/flutter_tools/lib/src/macos/xcode.dart b/packages/flutter_tools/lib/src/macos/xcode.dart
index a181927b74..be869d61d5 100644
--- a/packages/flutter_tools/lib/src/macos/xcode.dart
+++ b/packages/flutter_tools/lib/src/macos/xcode.dart
@@ -192,6 +192,15 @@ class Xcode {
);
}
+
+ Future<RunResult> dsymutil(List<String> args) {
+ return _processUtils.run(
+ <String>[...xcrunCommand(), 'dsymutil', ...args],
+ throwOnError: true,
+ );
+ }
+
+
Future<String> sdkLocation(EnvironmentType environmentType) async {
assert(environmentType != null);
final RunResult runResult = await _processUtils.run( This breaks @bruno-garcia do you think you (or somebody else from Sentry) will be able to take over this from here and land necessary changes in Flutter CLI and Dart's |
Modified Flutter CLI, build does not generate App.dSYM file? |
From the dart side, this is being worked on at https://dart-review.googlesource.com/c/sdk/+/242108 |
You mean you patched your Flutter with similar patch, run it and did not get dSYM? Did you make sure that Flutter CLI is recompiled by deleting |
Cool, clearing the cache this worked. already have a dSYM. thanks |
A |
TEST=vm/dart{,_2}/use_dwarf_stack_traces_flag Bug: #43612 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-mac-product-x64-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try Change-Id: Icda21bb14dcc0cf4784cea118e6ba7dd4edd35aa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250381 Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
…mation." This reverts commit 08c13f1. Reason for revert: Causing failures on simarm, simarm64, etc Original change's description: > [pkg/native_stack_traces] Support Mach-O dSYM debugging information. > > TEST=vm/dart{,_2}/use_dwarf_stack_traces_flag > > Bug: #43612 > Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-mac-product-x64-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try > Change-Id: Icda21bb14dcc0cf4784cea118e6ba7dd4edd35aa > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250381 > Commit-Queue: Tess Strickland <sstrickl@google.com> > Reviewed-by: Slava Egorov <vegorov@google.com> # Not skipping CQ checks because original CL landed > 1 day ago. Bug: #43612 Change-Id: I020c29f7329e9b53a8fe0f4f4a4de4070fca0ec3 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-mac-product-x64-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251242 Reviewed-by: Ben Konyi <bkonyi@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
…mation." This is a reland of commit 08c13f1 Fixes test failures on non-x64 architectures, both in the test harness and due to DWARF5 line number program headers having a non-backwards compatible format. (We generate DWARF2 in the ELF snapshot writer, but the assembler used for assembly snapshots may generate DWARF5.) TEST=vm/dart{,_2}/use_dwarf_stack_traces_flag Original change's description: > [pkg/native_stack_traces] Support Mach-O dSYM debugging information. > > TEST=vm/dart{,_2}/use_dwarf_stack_traces_flag > > Bug: #43612 > Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-mac-product-x64-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try > Change-Id: Icda21bb14dcc0cf4784cea118e6ba7dd4edd35aa > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250381 > Commit-Queue: Tess Strickland <sstrickl@google.com> > Reviewed-by: Slava Egorov <vegorov@google.com> Bug: #43612 Change-Id: I8a9cb70e78bc8594bcae004809c5a1be778d691d Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-mac-product-x64-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-nnbd-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-nnbd-mac-release-simarm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251464 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
Version 0.5.0 of |
I think @sstrickl has pushed it over the finish line and everything is working now as it should. |
Downstream feature request: flutter/flutter#60189
#35851 now supports translating obfuscated Dart stacks into the original stack, but as far as I understand, after applying --split-debug-info, we no longer have enough symbols left in the binary to then generate Xcode Debugging Symbols (dSym) from the binary/framework. This means users can no longer symbolize native call stacks into Dart call stacks.
Would it be possible for --split-debug-info to output both a obfuscated Dart -> Dart map as well as a native -> Dart map?
cc @sstrickl and @mraleph
The text was updated successfully, but these errors were encountered: