in github-label-notifier/symbolizer/lib/parser.dart [169:324]
void processLines() {
for (; lineNo < lines.length; lineNo++) {
var line = lines[lineNo];
// Strip markdown quote.
if (line.startsWith('> ')) {
line = line.substring(2);
}
// If we have an indication that we are processing raw logcat or flutter
// verbose output then strip the prefix characteristic for those log
// types.
if (logLinePattern != null) {
final m = logLinePattern.firstMatch(line);
if (m != null) {
line = m.namedGroup('rest');
} else {
// No longer in the raw log output. If we started collecting a crash
// flush it and continue handling the line.
endCrash();
}
}
if (line.isEmpty) {
continue;
}
// First check for crash markers.
if (line.contains(_androidCrashMarker)) {
// Start of the Android crash.
startCrash('android');
continue;
}
if (line.contains(_iosCrashMarker)) {
// Start of the iOS crash.
startCrash('ios');
continue;
}
final dartvmCrashMatch = _dartvmCrashMarker.firstMatch(line);
if (dartvmCrashMatch != null) {
startCrash(dartvmCrashMatch.namedGroup('os'));
format = 'dartvm';
arch = dartvmCrashMatch.namedGroup('arch');
if (arch == 'ia32') {
arch = 'x86';
}
continue;
}
if (format == 'dartvm') {
if (line.contains(_endOfDumpStackTracePattern)) {
endCrash();
continue;
}
final frameMatch = _dartvmFramePattern.firstMatch(line);
if (frameMatch != null) {
frames.add(CrashFrame.dartvm(
pc: int.parse(frameMatch.namedGroup('pc')),
binary: frameMatch.namedGroup('binary'),
offset: int.parse(frameMatch.namedGroup('offset')),
));
}
}
if (os == 'android') {
// Handle `Build fingerprint: '...'` line.
final androidVersion = _androidBuildFingerprintPattern
.firstMatch(line)
?.namedGroup('version');
if (androidVersion != null) {
androidMajorVersion = int.tryParse(androidVersion.split('.').first);
}
// Handle `ABI: '...'` line.
final abiMatch = _androidAbiPattern.firstMatch(line);
if (abiMatch != null) {
arch = abiMatch.namedGroup('abi');
if (arch == 'x86_64') {
arch = 'x64';
}
continue;
}
// Handle backtrace: start.
if (_backtraceStartPattern.hasMatch(line)) {
collectingFrames = true;
continue;
}
// If backtrace has started then process line corresponding for a frame.
if (collectingFrames) {
final frameMatch = _androidFramePattern.firstMatch(line);
if (frameMatch != null) {
final rest = frameMatch.namedGroup('rest');
final buildIdMatch = _buildIdPattern.firstMatch(rest);
frames.add(CrashFrame.android(
no: frameMatch.namedGroup('no'),
pc: int.parse(frameMatch.namedGroup('pc'), radix: 16),
binary: frameMatch.namedGroup('binary'),
rest: rest,
buildId: buildIdMatch?.namedGroup('id'),
));
} else {
endCrash();
}
}
continue;
}
if (os == 'ios') {
// Handle EOF marking the end of crash report.
if (line.contains(_eofPattern)) {
endCrash();
continue;
}
// Handle line that describes App.framework binary image.
// We use it as a marker to detect release mode builds.
if (line.contains(_appFrameworkPattern)) {
mode = 'release';
continue;
}
// Handle `Code Type: ...` line.
final abiMatch = _iosAbiPattern.firstMatch(line);
if (abiMatch != null) {
arch = abiMatch.namedGroup('abi') == 'ARM-64' ? 'arm64' : 'arm32';
continue;
}
// Handle `Thread ... Crashed:` line
if (line.contains(_crashedThreadPattern)) {
collectingFrames = true;
continue;
}
if (collectingFrames) {
final frame = parseIosFrame(line);
if (frame != null) {
frames.add(frame);
} else {
collectingFrames = false;
// Don't flush the crash yet - we want to read report until the
// end and check if it is a release build or not.
}
}
continue;
}
}
endCrash();
}