| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.crash; | 5 package org.chromium.chrome.browser.crash; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.Intent; | 8 import android.content.Intent; |
| 9 import android.util.Patterns; | 9 import android.util.Patterns; |
| 10 | 10 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 private static void move(File from, File to) { | 228 private static void move(File from, File to) { |
| 229 if (!from.renameTo(to)) { | 229 if (!from.renameTo(to)) { |
| 230 Log.w(TAG, "Fail to rename logcat file"); | 230 Log.w(TAG, "Fail to rename logcat file"); |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 | 233 |
| 234 @VisibleForTesting | 234 @VisibleForTesting |
| 235 protected List<String> getLogcat() throws IOException, InterruptedException
{ | 235 protected List<String> getLogcat() throws IOException, InterruptedException
{ |
| 236 // Grab the last lines of the logcat output, with a generous buffer to c
ompensate for any | 236 // Grab the last lines of the logcat output, with a generous buffer to c
ompensate for any |
| 237 // microdumps that might be in the logcat output, since microdumps are s
tripped in the | 237 // microdumps that might be in the logcat output, since microdumps are s
tripped in the |
| 238 // extraction code. | 238 // extraction code. Note that the repeated check of the process exit val
ue is to account for |
| 239 Process p = Runtime.getRuntime().exec("logcat -d | tail -n " + (LOGCAT_S
IZE * 4)); | 239 // the fact that the process might not finish immediately. And, it's no
t appropriate to |
| 240 // call p.waitFor(), because this call will block *forever* if the proce
ss's output buffer |
| 241 // fills up. |
| 242 Process p = Runtime.getRuntime().exec("logcat -d"); |
| 243 BufferedReader reader = new BufferedReader(new InputStreamReader(p.getIn
putStream())); |
| 244 LinkedList<String> rawLogcat = new LinkedList<>(); |
| 240 Integer exitValue = null; | 245 Integer exitValue = null; |
| 241 while (exitValue == null) { | 246 try { |
| 242 try { | 247 while (exitValue == null) { |
| 243 exitValue = p.exitValue(); | 248 String logLn; |
| 244 } catch (IllegalThreadStateException itse) { | 249 while ((logLn = reader.readLine()) != null) { |
| 245 Thread.sleep(HALF_SECOND); | 250 rawLogcat.add(logLn); |
| 251 if (rawLogcat.size() > LOGCAT_SIZE * 4) { |
| 252 rawLogcat.removeFirst(); |
| 253 } |
| 254 } |
| 255 |
| 256 try { |
| 257 exitValue = p.exitValue(); |
| 258 } catch (IllegalThreadStateException itse) { |
| 259 Thread.sleep(HALF_SECOND); |
| 260 } |
| 246 } | 261 } |
| 262 } finally { |
| 263 reader.close(); |
| 247 } | 264 } |
| 265 |
| 248 if (exitValue != 0) { | 266 if (exitValue != 0) { |
| 249 String msg = "Logcat failed: " + exitValue; | 267 String msg = "Logcat failed: " + exitValue; |
| 250 Log.w(TAG, msg); | 268 Log.w(TAG, msg); |
| 251 throw new IOException(msg); | 269 throw new IOException(msg); |
| 252 } | 270 } |
| 253 | 271 |
| 254 BufferedReader reader = new BufferedReader(new InputStreamReader(p.getIn
putStream())); | 272 return trimLogcat(rawLogcat, LOGCAT_SIZE); |
| 255 try { | |
| 256 return extractLogcatFromReader(reader, LOGCAT_SIZE); | |
| 257 } finally { | |
| 258 reader.close(); | |
| 259 } | |
| 260 } | 273 } |
| 261 | 274 |
| 262 /** | 275 /** |
| 263 * Extracts microdump-free logcat for more informative crash reports. Return
s the most recent | 276 * Extracts microdump-free logcat for more informative crash reports. Return
s the most recent |
| 264 * lines that are likely to be relevant to the crash, which are either the l
ines leading up to a | 277 * lines that are likely to be relevant to the crash, which are either the l
ines leading up to a |
| 265 * microdump if a microdump is present, or just the final lines of the logca
t if no microdump is | 278 * microdump if a microdump is present, or just the final lines of the logca
t if no microdump is |
| 266 * present. | 279 * present. |
| 267 * | 280 * |
| 268 * @param reader A buffered reader from which lines of initial logcat is rea
d. | 281 * @param rawLogcat The last lines of the raw logcat file, with sufficient h
istory to allow a |
| 282 * sufficient history even after trimming. |
| 269 * @param maxLines The maximum number of lines logcat extracts from minidump
. | 283 * @param maxLines The maximum number of lines logcat extracts from minidump
. |
| 270 * | 284 * |
| 271 * @return Logcat up to specified length as a list of strings. | 285 * @return Logcat up to specified length as a list of strings. |
| 272 * @throws IOException if the buffered reader encounters an I/O error. | |
| 273 */ | 286 */ |
| 274 @VisibleForTesting | 287 @VisibleForTesting |
| 275 protected static List<String> extractLogcatFromReader( | 288 protected static List<String> trimLogcat(List<String> rawLogcat, int maxLine
s) { |
| 276 BufferedReader reader, int maxLines) throws IOException { | |
| 277 // Slurp all of the lines. | |
| 278 List<String> rawLogcat = new LinkedList<>(); | |
| 279 String logLn; | |
| 280 while ((logLn = reader.readLine()) != null) { | |
| 281 rawLogcat.add(logLn); | |
| 282 } | |
| 283 | |
| 284 // Trim off the last microdump, and anything after it. | 289 // Trim off the last microdump, and anything after it. |
| 285 for (int i = rawLogcat.size() - 1; i >= 0; i--) { | 290 for (int i = rawLogcat.size() - 1; i >= 0; i--) { |
| 286 if (rawLogcat.get(i).contains(BEGIN_MICRODUMP)) { | 291 if (rawLogcat.get(i).contains(BEGIN_MICRODUMP)) { |
| 287 rawLogcat = rawLogcat.subList(0, i); | 292 rawLogcat = rawLogcat.subList(0, i); |
| 288 rawLogcat.add(SNIPPED_MICRODUMP); | 293 rawLogcat.add(SNIPPED_MICRODUMP); |
| 289 break; | 294 break; |
| 290 } | 295 } |
| 291 } | 296 } |
| 292 | 297 |
| 293 // Trim down the remainder to only contain the most recent lines. Thus,
if the original | 298 // Trim down the remainder to only contain the most recent lines. Thus,
if the original |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 * {@link #CONSOLE_ELISION}. | 421 * {@link #CONSOLE_ELISION}. |
| 417 * | 422 * |
| 418 * @param original String potentially containing console messages. | 423 * @param original String potentially containing console messages. |
| 419 * @return String with elided console messages. | 424 * @return String with elided console messages. |
| 420 */ | 425 */ |
| 421 @VisibleForTesting | 426 @VisibleForTesting |
| 422 protected static String elideConsole(String original) { | 427 protected static String elideConsole(String original) { |
| 423 return CONSOLE_MSG.matcher(original).replaceAll(CONSOLE_ELISION); | 428 return CONSOLE_MSG.matcher(original).replaceAll(CONSOLE_ELISION); |
| 424 } | 429 } |
| 425 } | 430 } |
| OLD | NEW |