| Index: chrome/android/java/src/org/chromium/chrome/browser/crash/LogcatExtractionCallable.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/LogcatExtractionCallable.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/LogcatExtractionCallable.java
|
| index 281708669fbd1ac10d7091decfcc20c0b49207d7..93fbff07809779d67c4460bf0cd608ca5ad4a64f 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/LogcatExtractionCallable.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/LogcatExtractionCallable.java
|
| @@ -90,6 +90,9 @@ public class LogcatExtractionCallable implements Callable<Boolean> {
|
| protected static final String BEGIN_MICRODUMP = "-----BEGIN BREAKPAD MICRODUMP-----";
|
| @VisibleForTesting
|
| protected static final String END_MICRODUMP = "-----END BREAKPAD MICRODUMP-----";
|
| + @VisibleForTesting
|
| + protected static final String SNIPPED_MICRODUMP =
|
| + "-----SNIPPED OUT BREAKPAD MICRODUMP FOR THIS CRASH-----";
|
|
|
| @VisibleForTesting
|
| protected static final String IP_ELISION = "1.2.3.4";
|
| @@ -230,41 +233,37 @@ public class LogcatExtractionCallable implements Callable<Boolean> {
|
|
|
| @VisibleForTesting
|
| protected List<String> getLogcat() throws IOException, InterruptedException {
|
| - return getLogcatInternal();
|
| - }
|
| -
|
| - private static List<String> getLogcatInternal() throws IOException, InterruptedException {
|
| - List<String> rawLogcat = null;
|
| + // Grab the last lines of the logcat output, with a generous buffer to compensate for any
|
| + // microdumps that might be in the logcat output, since microdumps are stripped in the
|
| + // extraction code.
|
| + Process p = Runtime.getRuntime().exec("logcat -d | tail -n " + (LOGCAT_SIZE * 4));
|
| Integer exitValue = null;
|
| - // In the absence of the android.permission.READ_LOGS permission the
|
| - // the logcat call will just hang.
|
| - Process p = Runtime.getRuntime().exec("logcat -d");
|
| - BufferedReader reader = null;
|
| - try {
|
| - reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
| - while (exitValue == null) {
|
| - rawLogcat = extractLogcatFromReader(reader, LOGCAT_SIZE);
|
| - try {
|
| - exitValue = p.exitValue();
|
| - } catch (IllegalThreadStateException itse) {
|
| - Thread.sleep(HALF_SECOND);
|
| - }
|
| - }
|
| - if (exitValue != 0) {
|
| - String msg = "Logcat failed: " + exitValue;
|
| - Log.w(TAG, msg);
|
| - throw new IOException(msg);
|
| + while (exitValue == null) {
|
| + try {
|
| + exitValue = p.exitValue();
|
| + } catch (IllegalThreadStateException itse) {
|
| + Thread.sleep(HALF_SECOND);
|
| }
|
| - return rawLogcat;
|
| + }
|
| + if (exitValue != 0) {
|
| + String msg = "Logcat failed: " + exitValue;
|
| + Log.w(TAG, msg);
|
| + throw new IOException(msg);
|
| + }
|
| +
|
| + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
| + try {
|
| + return extractLogcatFromReader(reader, LOGCAT_SIZE);
|
| } finally {
|
| - if (reader != null) {
|
| - reader.close();
|
| - }
|
| + reader.close();
|
| }
|
| }
|
|
|
| /**
|
| - * Extract microdump-free logcat for more informative crash reports
|
| + * Extracts microdump-free logcat for more informative crash reports. Returns the most recent
|
| + * lines that are likely to be relevant to the crash, which are either the lines leading up to a
|
| + * microdump if a microdump is present, or just the final lines of the logcat if no microdump is
|
| + * present.
|
| *
|
| * @param reader A buffered reader from which lines of initial logcat is read.
|
| * @param maxLines The maximum number of lines logcat extracts from minidump.
|
| @@ -275,33 +274,29 @@ public class LogcatExtractionCallable implements Callable<Boolean> {
|
| @VisibleForTesting
|
| protected static List<String> extractLogcatFromReader(
|
| BufferedReader reader, int maxLines) throws IOException {
|
| - return extractLogcatFromReaderInternal(reader, maxLines);
|
| - }
|
| -
|
| - private static List<String> extractLogcatFromReaderInternal(
|
| - BufferedReader reader, int maxLines) throws IOException {
|
| - boolean inMicrodump = false;
|
| + // Slurp all of the lines.
|
| List<String> rawLogcat = new LinkedList<>();
|
| String logLn;
|
| - while ((logLn = reader.readLine()) != null && rawLogcat.size() < maxLines) {
|
| - if (logLn.contains(BEGIN_MICRODUMP)) {
|
| - // If the log contains two begin markers without an end marker
|
| - // in between, we ignore the second begin marker.
|
| - inMicrodump = true;
|
| - } else if (logLn.contains(END_MICRODUMP)) {
|
| - if (!inMicrodump) {
|
| - // If we have been extracting microdump the whole time,
|
| - // start over with a clean logcat.
|
| - rawLogcat.clear();
|
| - } else {
|
| - inMicrodump = false;
|
| - }
|
| - } else {
|
| - if (!inMicrodump) {
|
| - rawLogcat.add(logLn);
|
| - }
|
| + while ((logLn = reader.readLine()) != null) {
|
| + rawLogcat.add(logLn);
|
| + }
|
| +
|
| + // Trim off the last microdump, and anything after it.
|
| + for (int i = rawLogcat.size() - 1; i >= 0; i--) {
|
| + if (rawLogcat.get(i).contains(BEGIN_MICRODUMP)) {
|
| + rawLogcat = rawLogcat.subList(0, i);
|
| + rawLogcat.add(SNIPPED_MICRODUMP);
|
| + break;
|
| }
|
| }
|
| +
|
| + // Trim down the remainder to only contain the most recent lines. Thus, if the original
|
| + // input contained a microdump, the result contains the most recent lines before the
|
| + // microdump, which are most likely to be relevant to the crash. If there is no microdump
|
| + // in the raw logcat, then just hope that the last lines in the dump are relevant.
|
| + if (rawLogcat.size() > maxLines) {
|
| + rawLogcat = rawLogcat.subList(rawLogcat.size() - maxLines, rawLogcat.size());
|
| + }
|
| return rawLogcat;
|
| }
|
|
|
|
|