5633c40d39
Change-Id: I7d865d8c4d2fc7145a2c0567252edafba058b9e4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400741 Commit-Queue: Mayank Patke <fishythefish@google.com> Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Nate Biggs <natebiggs@google.com> Auto-Submit: Mayank Patke <fishythefish@google.com>
64 lines
2.6 KiB
Dart
64 lines
2.6 KiB
Dart
import 'dart:math' show max;
|
|
|
|
import 'package:dart2js_tools/src/name_decoder.dart';
|
|
import 'package:dart2js_tools/src/trace.dart';
|
|
import 'package:dart2js_tools/src/trace_decoder.dart';
|
|
import 'package:dart2js_tools/src/util.dart';
|
|
import 'package:stack_trace/stack_trace.dart';
|
|
|
|
/// Deobfuscates the given [obfuscatedTrace].
|
|
///
|
|
/// This method assumes a stack trace contains URIs normalized to be file URIs.
|
|
/// If for example you obtain a stack from a browser, you may need to preprocess
|
|
/// the stack to map the URI of the JavaScript files to URIs in the local file
|
|
/// system.
|
|
///
|
|
/// For example, a valid input to this method would be:
|
|
///
|
|
/// Error: no such method
|
|
/// at aB.a20 (/usr/local/foo/main.dart.js:71969:32)
|
|
/// at aNk.goV (/usr/local/foo/main.dart.js:72040:52)
|
|
/// at aNk.gfK (/usr/local/foo/main.dart.js:72038:27)
|
|
/// at FE.gtn (/usr/local/foo/main.dart.js:72640:24)
|
|
/// at aBZ.ghN (/usr/local/foo/main.dart.js:72642:24)
|
|
/// at inheritance (/usr/local/foo/main.dart.js:105334:0)
|
|
/// at FE (/usr/local/foo/main.dart.js:5037:18)
|
|
///
|
|
/// Internally this method will read those JavaScript files, search for the
|
|
/// `//# sourceMappingURL=` line at the end, and load the corresponding
|
|
/// source-map file.
|
|
String deobfuscateStackTrace(String obfuscatedTrace) {
|
|
String? error = extractErrorMessage(obfuscatedTrace);
|
|
var provider = CachingFileProvider();
|
|
StackDeobfuscationResult result = deobfuscateStack(obfuscatedTrace, provider);
|
|
Frame firstFrame = result.original.frames.first;
|
|
String translatedError =
|
|
(firstFrame.uri.isScheme('error')
|
|
? null
|
|
: translate(error, provider.mappingFor(firstFrame.uri))) ??
|
|
'<no error message found>';
|
|
|
|
var sb = StringBuffer();
|
|
sb.writeln(translatedError);
|
|
maxMemberLengthHelper(int m, Frame f) => max(f.member!.length, m);
|
|
int longest = result.deobfuscated.frames.fold(0, maxMemberLengthHelper);
|
|
longest = result.original.frames.fold(longest, maxMemberLengthHelper);
|
|
for (var originalFrame in result.original.frames) {
|
|
var deobfuscatedFrames = result.frameMap[originalFrame];
|
|
if (deobfuscatedFrames == null) {
|
|
var name = originalFrame.member;
|
|
sb.writeln(' at ${name!.padRight(longest)} ${originalFrame.location}');
|
|
} else {
|
|
for (var frame in deobfuscatedFrames) {
|
|
var name = frame.member;
|
|
// TODO(sigmund): eventually when ddc stops shipping source-maps to the
|
|
// client, we can start encoding the function name and remove this
|
|
// workaround.
|
|
if (name == '<unknown>') name = originalFrame.member;
|
|
sb.writeln(' at ${name!.padRight(longest)} ${frame.location}');
|
|
}
|
|
}
|
|
}
|
|
return '$sb';
|
|
}
|