Home | History | Annotate | Download | only in anr
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.bugreport.anr;
     18 
     19 import com.android.bugreport.cpuinfo.CpuUsageParser;
     20 import com.android.bugreport.cpuinfo.CpuUsageSnapshot;
     21 import com.android.bugreport.util.Utils;
     22 import com.android.bugreport.util.Line;
     23 import com.android.bugreport.util.Lines;
     24 import com.android.bugreport.stacks.ProcessSnapshot;
     25 import com.android.bugreport.stacks.ProcessSnapshotParser;
     26 import com.android.bugreport.stacks.VmTraces;
     27 
     28 import java.io.BufferedReader;
     29 import java.io.IOException;
     30 import java.util.ArrayList;
     31 import java.util.regex.Pattern;
     32 import java.util.regex.Matcher;
     33 
     34 /**
     35  * Parse an anr block from a monkey log.
     36  *
     37  * The parser can be reused, but is not thread safe.
     38  */
     39 public class AnrParser {
     40     private static final Pattern PROC_NAME_RE
     41             = Pattern.compile("ANR in (\\S+) \\((\\S+)/(\\S+)\\)");
     42     private static final Pattern PID_RE
     43             = Pattern.compile("PID: (\\d+)");
     44     private static final Pattern REASON_RE
     45             = Pattern.compile("Reason: (.*)");
     46     private static final Pattern BLANK_RE
     47             = Pattern.compile("\\s+");
     48 
     49     /**
     50      * Construct a new parser.
     51      */
     52     public AnrParser() {
     53     }
     54 
     55     /**
     56      * Do the parsing.
     57      */
     58     public ArrayList<Anr> parse(Lines<? extends Line> lines, boolean tryTraces) {
     59         final ArrayList<Anr> results = new ArrayList<Anr>();
     60         Anr anr = null;
     61 
     62         final Matcher procNameRe = PROC_NAME_RE.matcher("");
     63         final Matcher pidRe = PID_RE.matcher("");
     64         final Matcher reasonRe = REASON_RE.matcher("");
     65         final Matcher cpuUsageRe = CpuUsageParser.CPU_USAGE_RE.matcher("");
     66         final Matcher beginProcessRe = ProcessSnapshotParser.BEGIN_PROCESS_RE.matcher("");
     67 
     68         while (lines.hasNext()) {
     69             final Line line = lines.next();
     70             final String text = line.text;
     71             if (Utils.matches(procNameRe, text)) {
     72                 anr = new Anr();
     73                 anr.vmTraces = new VmTraces();
     74                 results.add(anr);
     75                 anr.processName = procNameRe.group(1);
     76                 anr.componentPackage = procNameRe.group(2);
     77                 anr.componentClass = procNameRe.group(3);
     78             } else if (Utils.matches(pidRe, text)) {
     79                 if (anr != null) {
     80                     anr.pid = Integer.parseInt(pidRe.group(1));
     81                 }
     82             } else if (Utils.matches(reasonRe, text)) {
     83                 if (anr != null) {
     84                     anr.reason = reasonRe.group(1);
     85                 }
     86             } else if (Utils.matches(cpuUsageRe, text)) {
     87                 if (anr != null) {
     88                     lines.rewind();
     89                     CpuUsageParser parser = new CpuUsageParser();
     90                     final CpuUsageSnapshot snapshot = parser.parse(lines);
     91                     if (snapshot != null) {
     92                         anr.cpuUsages.add(snapshot);
     93                     } else {
     94                         // TODO: Try to backtrack and correct the parsing.
     95                     }
     96                 }
     97             } else if (Utils.matches(beginProcessRe, text)) {
     98                 if (tryTraces && anr != null) {
     99                     lines.rewind();
    100                     ProcessSnapshotParser parser = new ProcessSnapshotParser();
    101                     final ProcessSnapshot snapshot = parser.parse(lines);
    102                     if (snapshot != null) {
    103                         anr.vmTraces.processes.add(snapshot);
    104                     } else {
    105                         // TODO: Try to backtrack and correct the parsing.
    106                     }
    107                 }
    108             } else {
    109                 // Unknown
    110                 //
    111                 // TODO: These lines:
    112                 //      Load: 16.37 / 7.19 / 2.73
    113                 //      procrank:
    114                 if (false) {
    115                     System.out.println("AnrParser Dropping: " + text);
    116                 }
    117             }
    118         }
    119 
    120         if (false) {
    121             for (Anr item: results) {
    122                 System.out.println("ANR");
    123                 System.out.println("  processName=" + item.processName);
    124                 System.out.println("  componentPackage=" + item.componentPackage);
    125                 System.out.println("  componentClass=" + item.componentClass);
    126                 System.out.println("  pid=" + item.pid);
    127                 System.out.println("  reason=" + item.reason);
    128             }
    129         }
    130 
    131         return results;
    132     }
    133 
    134 }
    135 
    136