Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
56817279
Unverified
Commit
56817279
authored
Feb 10, 2020
by
Jonah Williams
Committed by
GitHub
Feb 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add "flutter symbolize" command (#49465)
parent
ffc85591
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
277 additions
and
6 deletions
+277
-6
BUILD.gn
packages/flutter_tools/BUILD.gn
+2
-1
executable.dart
packages/flutter_tools/lib/executable.dart
+6
-0
symbolize.dart
packages/flutter_tools/lib/src/commands/symbolize.dart
+162
-0
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+1
-2
pubspec.yaml
packages/flutter_tools/pubspec.yaml
+4
-3
symbolize_test.dart
...er_tools/test/commands.shard/hermetic/symbolize_test.dart
+102
-0
No files found.
packages/flutter_tools/BUILD.gn
View file @
56817279
...
@@ -34,6 +34,8 @@ dart_library("flutter_tools") {
...
@@ -34,6 +34,8 @@ dart_library("flutter_tools") {
"//third_party/dart-pkg/pub/multi_server_socket",
"//third_party/dart-pkg/pub/multi_server_socket",
"//third_party/dart-pkg/pub/multicast_dns",
"//third_party/dart-pkg/pub/multicast_dns",
"//third_party/dart-pkg/pub/mustache",
"//third_party/dart-pkg/pub/mustache",
"//third_party/dart-pkg/pub/native_stack_traces",
"//third_party/dart-pkg/pub/node_preamble",
"//third_party/dart-pkg/pub/package_config",
"//third_party/dart-pkg/pub/package_config",
"//third_party/dart-pkg/pub/path",
"//third_party/dart-pkg/pub/path",
"//third_party/dart-pkg/pub/platform",
"//third_party/dart-pkg/pub/platform",
...
@@ -51,7 +53,6 @@ dart_library("flutter_tools") {
...
@@ -51,7 +53,6 @@ dart_library("flutter_tools") {
"//third_party/dart-pkg/pub/webkit_inspection_protocol",
"//third_party/dart-pkg/pub/webkit_inspection_protocol",
"//third_party/dart-pkg/pub/xml",
"//third_party/dart-pkg/pub/xml",
"//third_party/dart-pkg/pub/yaml",
"//third_party/dart-pkg/pub/yaml",
"//third_party/dart-pkg/pub/node_preamble",
]
]
}
}
...
...
packages/flutter_tools/lib/executable.dart
View file @
56817279
...
@@ -39,12 +39,14 @@ import 'src/commands/precache.dart';
...
@@ -39,12 +39,14 @@ import 'src/commands/precache.dart';
import
'src/commands/run.dart'
;
import
'src/commands/run.dart'
;
import
'src/commands/screenshot.dart'
;
import
'src/commands/screenshot.dart'
;
import
'src/commands/shell_completion.dart'
;
import
'src/commands/shell_completion.dart'
;
import
'src/commands/symbolize.dart'
;
import
'src/commands/test.dart'
;
import
'src/commands/test.dart'
;
import
'src/commands/train.dart'
;
import
'src/commands/train.dart'
;
import
'src/commands/unpack.dart'
;
import
'src/commands/unpack.dart'
;
import
'src/commands/update_packages.dart'
;
import
'src/commands/update_packages.dart'
;
import
'src/commands/upgrade.dart'
;
import
'src/commands/upgrade.dart'
;
import
'src/commands/version.dart'
;
import
'src/commands/version.dart'
;
import
'src/globals.dart'
as
globals
;
import
'src/runner/flutter_command.dart'
;
import
'src/runner/flutter_command.dart'
;
import
'src/web/compile.dart'
;
import
'src/web/compile.dart'
;
import
'src/web/web_runner.dart'
;
import
'src/web/web_runner.dart'
;
...
@@ -94,6 +96,10 @@ Future<void> main(List<String> args) async {
...
@@ -94,6 +96,10 @@ Future<void> main(List<String> args) async {
UpdatePackagesCommand
(
hidden:
!
verboseHelp
),
UpdatePackagesCommand
(
hidden:
!
verboseHelp
),
UpgradeCommand
(),
UpgradeCommand
(),
VersionCommand
(),
VersionCommand
(),
SymbolizeCommand
(
stdio:
globals
.
stdio
,
fileSystem:
globals
.
fs
,
),
],
verbose:
verbose
,
],
verbose:
verbose
,
muteCommandLogging:
muteCommandLogging
,
muteCommandLogging:
muteCommandLogging
,
verboseHelp:
verboseHelp
,
verboseHelp:
verboseHelp
,
...
...
packages/flutter_tools/lib/src/commands/symbolize.dart
0 → 100644
View file @
56817279
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:typed_data'
;
import
'package:meta/meta.dart'
;
import
'package:native_stack_traces/native_stack_traces.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../convert.dart'
;
import
'../runner/flutter_command.dart'
;
/// Support for symbolicating a Dart stack trace.
///
/// This command accepts either paths to an input file containing the
/// stack trace and an output file for the symbolicated trace to be
/// written, or it accepts a stack trace over stdin and outputs it
/// over stdout.
class
SymbolizeCommand
extends
FlutterCommand
{
SymbolizeCommand
({
@required
Stdio
stdio
,
@required
FileSystem
fileSystem
,
DwarfSymbolizationService
dwarfSymbolizationService
=
const
DwarfSymbolizationService
(),
})
:
_stdio
=
stdio
,
_fileSystem
=
fileSystem
,
_dwarfSymbolizationService
=
dwarfSymbolizationService
{
argParser
.
addOption
(
'debug-info'
,
abbr:
'd'
,
valueHelp:
'/out/android/app.arm64.symbols'
,
help:
'A path to the symbols file generated with "--split-debug-info".'
);
argParser
.
addOption
(
'input'
,
abbr:
'i'
,
valueHelp:
'/crashes/stack_trace.err'
,
help:
'A file path containing a Dart stack trace.'
);
argParser
.
addOption
(
'output'
,
abbr:
'o'
,
valueHelp:
'A file path for a symbolicated stack trace to be written to.'
);
}
final
Stdio
_stdio
;
final
FileSystem
_fileSystem
;
final
DwarfSymbolizationService
_dwarfSymbolizationService
;
@override
String
get
description
=>
'Symbolize a stack trace from an AOT compiled flutter application.'
;
@override
String
get
name
=>
'symbolize'
;
@override
bool
get
shouldUpdateCache
=>
false
;
@override
Future
<
void
>
validateCommand
()
{
if
(!
argResults
.
wasParsed
(
'debug-info'
))
{
throwToolExit
(
'"--debug-info" is required to symbolicate stack traces.'
);
}
if
(!
_fileSystem
.
isFileSync
(
stringArg
(
'debug-info'
)))
{
throwToolExit
(
'
${stringArg('debug-info')}
does not exist.'
);
}
if
(
argResults
.
wasParsed
(
'input'
)
&&
!
_fileSystem
.
isFileSync
(
stringArg
(
'input'
)))
{
throwToolExit
(
'
${stringArg('input')}
does not exist.'
);
}
return
super
.
validateCommand
();
}
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
Stream
<
List
<
int
>>
input
;
IOSink
output
;
// Configure output to either specified file or stdout.
if
(
argResults
.
wasParsed
(
'output'
))
{
final
File
outputFile
=
_fileSystem
.
file
(
stringArg
(
'output'
));
if
(!
outputFile
.
parent
.
existsSync
())
{
outputFile
.
parent
.
createSync
(
recursive:
true
);
}
output
=
outputFile
.
openWrite
();
}
else
{
final
StreamController
<
List
<
int
>>
outputController
=
StreamController
<
List
<
int
>>();
outputController
.
stream
.
transform
(
utf8
.
decoder
)
.
listen
(
_stdio
.
stdoutWrite
);
output
=
IOSink
(
outputController
);
}
// Configure input from either specified file or stdin.
if
(
argResults
.
wasParsed
(
'input'
))
{
input
=
_fileSystem
.
file
(
stringArg
(
'input'
)).
openRead
();
}
else
{
input
=
_stdio
.
stdin
;
}
final
Uint8List
symbols
=
_fileSystem
.
file
(
stringArg
(
'debug-info'
)).
readAsBytesSync
();
await
_dwarfSymbolizationService
.
decode
(
input:
input
,
output:
output
,
symbols:
symbols
,
);
return
FlutterCommandResult
.
success
();
}
}
/// A service which decodes stack traces from Dart applications.
class
DwarfSymbolizationService
{
const
DwarfSymbolizationService
();
/// Decode a stack trace from [input] and place the results in [output].
///
/// Requires [symbols] to be a buffer created from the `--split-debug-info`
/// command line flag.
///
/// Throws a [ToolExit] if the symbols cannot be parsed or the stack trace
/// cannot be decoded.
Future
<
void
>
decode
({
@required
Stream
<
List
<
int
>>
input
,
@required
IOSink
output
,
@required
Uint8List
symbols
,
})
async
{
final
Dwarf
dwarf
=
Dwarf
.
fromBytes
(
symbols
);
if
(
dwarf
==
null
)
{
throwToolExit
(
'Failed to decode symbols file'
);
}
final
Completer
<
void
>
onDone
=
Completer
<
void
>();
StreamSubscription
<
void
>
subscription
;
subscription
=
input
.
transform
(
const
Utf8Decoder
())
.
transform
(
const
LineSplitter
())
.
transform
(
DwarfStackTraceDecoder
(
dwarf
,
includeInternalFrames:
true
))
.
listen
((
String
line
)
{
try
{
output
.
writeln
(
line
);
}
on
Exception
catch
(
e
,
s
)
{
subscription
.
cancel
().
whenComplete
(()
{
if
(!
onDone
.
isCompleted
)
{
onDone
.
completeError
(
e
,
s
);
}
});
}
},
onDone:
onDone
.
complete
,
onError:
onDone
.
completeError
);
try
{
await
onDone
.
future
;
await
output
.
close
();
}
on
Exception
catch
(
err
)
{
throwToolExit
(
'Failed to symbolize stack trace:
\n
$err
'
);
}
}
}
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
56817279
...
@@ -375,8 +375,7 @@ abstract class FlutterCommand extends Command<void> {
...
@@ -375,8 +375,7 @@ abstract class FlutterCommand extends Command<void> {
'symbol files can be stored for later use. These symbol files contain '
'symbol files can be stored for later use. These symbol files contain '
'the information needed to symbolize Dart stack traces. For an app built '
'the information needed to symbolize Dart stack traces. For an app built '
'with this flag, the
\'
flutter symbolize
\'
command with the right program '
'with this flag, the
\'
flutter symbolize
\'
command with the right program '
'symbol file is required to obtain a human readable stack trace. This '
'symbol file is required to obtain a human readable stack trace.'
,
'command is tracked by https://github.com/flutter/flutter/issues/50206'
,
valueHelp:
'/project-name/v1.2.3/'
,
valueHelp:
'/project-name/v1.2.3/'
,
);
);
}
}
...
...
packages/flutter_tools/pubspec.yaml
View file @
56817279
...
@@ -35,6 +35,7 @@ dependencies:
...
@@ -35,6 +35,7 @@ dependencies:
webkit_inspection_protocol
:
0.5.0
webkit_inspection_protocol
:
0.5.0
xml
:
3.5.0
xml
:
3.5.0
yaml
:
2.2.0
yaml
:
2.2.0
native_stack_traces
:
0.2.2
flutter_goldens_client
:
flutter_goldens_client
:
path
:
../flutter_goldens_client
path
:
../flutter_goldens_client
...
@@ -62,12 +63,12 @@ dependencies:
...
@@ -62,12 +63,12 @@ dependencies:
build_config
:
0.4.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
build_config
:
0.4.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
build_resolvers
:
1.3.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
build_resolvers
:
1.3.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_collection
:
4.3.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_collection
:
4.3.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_value
:
7.0.
8
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_value
:
7.0.
9
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
charcode
:
1.1.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
charcode
:
1.1.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
checked_yaml
:
1.0.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
checked_yaml
:
1.0.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert
:
2.1.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert
:
2.1.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib
:
0.16.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib
:
0.16.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
devtools
:
0.1.1
4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
devtools
:
0.1.1
5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
devtools_server
:
0.1.13
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
devtools_server
:
0.1.13
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fixnum
:
0.10.11
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fixnum
:
0.10.11
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob
:
1.2.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob
:
1.2.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
@@ -127,4 +128,4 @@ dartdoc:
...
@@ -127,4 +128,4 @@ dartdoc:
# Exclude this package from the hosted API docs.
# Exclude this package from the hosted API docs.
nodoc
:
true
nodoc
:
true
# PUBSPEC CHECKSUM:
3a4b
# PUBSPEC CHECKSUM:
557d
packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart
0 → 100644
View file @
56817279
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:typed_data'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/symbolize.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/mocks.dart'
;
void
main
(
)
{
MemoryFileSystem
fileSystem
;
MockStdio
stdio
;
SymbolizeCommand
command
;
MockDwarfSymbolizationService
mockDwarfSymbolizationService
;
setUpAll
(()
{
Cache
.
disableLocking
();
});
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
stdio
=
MockStdio
();
mockDwarfSymbolizationService
=
MockDwarfSymbolizationService
();
command
=
SymbolizeCommand
(
stdio:
stdio
,
fileSystem:
fileSystem
,
dwarfSymbolizationService:
mockDwarfSymbolizationService
,
);
applyMocksToCommand
(
command
);
});
testUsingContext
(
'symbolize exits when --debug-info argument is missing'
,
()
async
{
final
Future
<
void
>
result
=
createTestCommandRunner
(
command
)
.
run
(
const
<
String
>[
'symbolize'
]);
expect
(
result
,
throwsToolExit
(
message:
'"--debug-info" is required to symbolicate stack traces.'
));
});
testUsingContext
(
'symbolize exits when --debug-info file is missing'
,
()
async
{
final
Future
<
void
>
result
=
createTestCommandRunner
(
command
)
.
run
(
const
<
String
>[
'symbolize'
,
'--debug-info=app.debug'
]);
expect
(
result
,
throwsToolExit
(
message:
'app.debug does not exist.'
));
});
testUsingContext
(
'symbolize exits when --input file is missing'
,
()
async
{
fileSystem
.
file
(
'app.debug'
).
createSync
();
final
Future
<
void
>
result
=
createTestCommandRunner
(
command
)
.
run
(
const
<
String
>[
'symbolize'
,
'--debug-info=app.debug'
,
'--input=foo.stack'
,
'--output=results/foo.result'
]);
expect
(
result
,
throwsToolExit
(
message:
''
));
});
testUsingContext
(
'symbolize succeedes when DwarfSymbolizationService does not throw'
,
()
async
{
fileSystem
.
file
(
'app.debug'
).
writeAsBytesSync
(<
int
>[
1
,
2
,
3
]);
fileSystem
.
file
(
'foo.stack'
).
writeAsStringSync
(
'hello'
);
when
(
mockDwarfSymbolizationService
.
decode
(
input:
anyNamed
(
'input'
),
output:
anyNamed
(
'output'
),
symbols:
anyNamed
(
'symbols'
))
).
thenAnswer
((
Invocation
invocation
)
async
{
// Data is passed correctly to service
expect
((
await
(
invocation
.
namedArguments
[
#input
]
as
Stream
<
List
<
int
>>).
toList
()).
first
,
utf8
.
encode
(
'hello'
));
expect
(
invocation
.
namedArguments
[
#symbols
]
as
Uint8List
,
<
int
>[
1
,
2
,
3
,]);
return
;
});
await
createTestCommandRunner
(
command
)
.
run
(
const
<
String
>[
'symbolize'
,
'--debug-info=app.debug'
,
'--input=foo.stack'
,
'--output=results/foo.result'
]);
});
testUsingContext
(
'symbolize throws when DwarfSymbolizationService throws'
,
()
async
{
fileSystem
.
file
(
'app.debug'
).
writeAsBytesSync
(<
int
>[
1
,
2
,
3
]);
fileSystem
.
file
(
'foo.stack'
).
writeAsStringSync
(
'hello'
);
when
(
mockDwarfSymbolizationService
.
decode
(
input:
anyNamed
(
'input'
),
output:
anyNamed
(
'output'
),
symbols:
anyNamed
(
'symbols'
))
).
thenThrow
(
ToolExit
(
'test'
));
expect
(
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'symbolize'
,
'--debug-info=app.debug'
,
'--input=foo.stack'
,
'--output=results/foo.result'
]),
throwsToolExit
(
message:
'test'
),
);
});
}
class
MockDwarfSymbolizationService
extends
Mock
implements
DwarfSymbolizationService
{}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment