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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 } | 223 } |
224 | 224 |
225 private static void move(File from, File to) { | 225 private static void move(File from, File to) { |
226 if (!from.renameTo(to)) { | 226 if (!from.renameTo(to)) { |
227 Log.w(TAG, "Fail to rename logcat file"); | 227 Log.w(TAG, "Fail to rename logcat file"); |
228 } | 228 } |
229 } | 229 } |
230 | 230 |
231 @VisibleForTesting | 231 @VisibleForTesting |
232 protected List<String> getLogcat() throws IOException, InterruptedException { | 232 protected List<String> getLogcat() throws IOException, InterruptedException { |
233 return getLogcatInternal(); | 233 List<String> rawLogcat = new LinkedList<>(); |
234 } | 234 boolean inMicrodump = false; |
235 | 235 |
236 private static List<String> getLogcatInternal() throws IOException, Interrup tedException { | |
237 List<String> rawLogcat = null; | |
238 Integer exitValue = null; | 236 Integer exitValue = null; |
239 // In the absence of the android.permission.READ_LOGS permission the | 237 // In the absence of the android.permission.READ_LOGS permission, the lo gcat call will just |
240 // the logcat call will just hang. | 238 // hang. |
Ilya Sherman
2016/09/01 02:00:03
FWIW, I don't understand the relevance of this com
acleung1
2016/09/01 17:54:42
This comment is some what irrelevant. The issue is
Ilya Sherman
2016/09/01 21:46:58
Okay, removed -- thanks.
| |
241 Process p = Runtime.getRuntime().exec("logcat -d"); | 239 Process p = Runtime.getRuntime().exec("logcat -d"); |
242 BufferedReader reader = null; | 240 BufferedReader reader = null; |
243 try { | 241 try { |
244 reader = new BufferedReader(new InputStreamReader(p.getInputStream() )); | 242 reader = new BufferedReader(new InputStreamReader(p.getInputStream() )); |
245 while (exitValue == null) { | 243 while (exitValue == null) { |
246 rawLogcat = extractLogcatFromReader(reader, LOGCAT_SIZE); | 244 inMicrodump = |
245 extractLogcatChunkFromReader(reader, LOGCAT_SIZE, inMicr odump, rawLogcat); | |
Ilya Sherman
2016/09/01 02:00:03
It feels kind of hacky to read the logcat in chunk
acleung1
2016/09/01 17:54:42
Not that I know of.
Ilya Sherman
2016/09/01 21:46:58
Maria, WDYT?
| |
247 try { | 246 try { |
248 exitValue = p.exitValue(); | 247 exitValue = p.exitValue(); |
249 } catch (IllegalThreadStateException itse) { | 248 } catch (IllegalThreadStateException itse) { |
249 // The logcat dump has not yet completed; give it some more time. | |
250 Thread.sleep(HALF_SECOND); | 250 Thread.sleep(HALF_SECOND); |
251 } | 251 } |
252 } | 252 } |
253 if (exitValue != 0) { | 253 if (exitValue != 0) { |
254 String msg = "Logcat failed: " + exitValue; | 254 String msg = "Logcat failed: " + exitValue; |
255 Log.w(TAG, msg); | 255 Log.w(TAG, msg); |
256 throw new IOException(msg); | 256 throw new IOException(msg); |
257 } | 257 } |
258 return rawLogcat; | 258 return rawLogcat; |
259 } finally { | 259 } finally { |
260 if (reader != null) { | 260 if (reader != null) { |
261 reader.close(); | 261 reader.close(); |
262 } | 262 } |
263 } | 263 } |
264 } | 264 } |
265 | 265 |
266 /** | 266 /** |
267 * Extract microdump-free logcat for more informative crash reports | 267 * Extract microdump-free logcat for more informative crash reports |
268 * | 268 * |
269 * @param reader A buffered reader from which lines of initial logcat is rea d. | 269 * @param reader A buffered reader from which lines of initial logcat is rea d. |
270 * @param maxLines The maximum number of lines logcat extracts from minidump . | 270 * @param maxLines The maximum number of lines logcat extracts from logcat. |
271 * @param inMicrodump Whether the upcoming lines in the logcat are known to be part of a | |
272 * microdump. | |
273 * @param rawLogcat The tail of the logcat that has been read so far, as a l ist of strings. | |
271 * | 274 * |
272 * @return Logcat up to specified length as a list of strings. | 275 * @return Whether the next lines to be read from the logcat are known to be part of a |
276 * microdump. | |
273 * @throws IOException if the buffered reader encounters an I/O error. | 277 * @throws IOException if the buffered reader encounters an I/O error. |
274 */ | 278 */ |
275 @VisibleForTesting | 279 @VisibleForTesting |
276 protected static List<String> extractLogcatFromReader( | 280 protected static boolean extractLogcatChunkFromReader(BufferedReader reader, int maxLines, |
277 BufferedReader reader, int maxLines) throws IOException { | 281 boolean inMicrodump, List<String> rawLogcat) throws IOException { |
278 return extractLogcatFromReaderInternal(reader, maxLines); | |
279 } | |
280 | |
281 private static List<String> extractLogcatFromReaderInternal( | |
282 BufferedReader reader, int maxLines) throws IOException { | |
283 boolean inMicrodump = false; | |
284 List<String> rawLogcat = new LinkedList<>(); | |
285 String logLn; | 282 String logLn; |
286 while ((logLn = reader.readLine()) != null && rawLogcat.size() < maxLine s) { | 283 while ((logLn = reader.readLine()) != null) { |
287 if (logLn.contains(BEGIN_MICRODUMP)) { | 284 if (logLn.contains(BEGIN_MICRODUMP)) { |
288 // If the log contains two begin markers without an end marker | 285 // If the log contains two begin markers without an end marker |
289 // in between, we ignore the second begin marker. | 286 // in between, we ignore the second begin marker. |
290 inMicrodump = true; | 287 inMicrodump = true; |
291 } else if (logLn.contains(END_MICRODUMP)) { | 288 } else if (logLn.contains(END_MICRODUMP)) { |
292 if (!inMicrodump) { | 289 if (!inMicrodump) { |
293 // If we have been extracting microdump the whole time, | 290 // If we have been extracting microdump the whole time, |
294 // start over with a clean logcat. | 291 // start over with a clean logcat. |
295 rawLogcat.clear(); | 292 rawLogcat.clear(); |
296 } else { | 293 } else { |
297 inMicrodump = false; | 294 inMicrodump = false; |
298 } | 295 } |
299 } else { | 296 } else { |
300 if (!inMicrodump) { | 297 if (!inMicrodump) { |
301 rawLogcat.add(logLn); | 298 rawLogcat.add(logLn); |
299 if (rawLogcat.size() > maxLines) { | |
300 rawLogcat.remove(0); | |
301 } | |
302 } | 302 } |
303 } | 303 } |
304 } | 304 } |
305 return rawLogcat; | 305 return inMicrodump; |
306 } | 306 } |
307 | 307 |
308 private File writeLogcat(List<String> elidedLogcat) throws IOException { | 308 private File writeLogcat(List<String> elidedLogcat) throws IOException { |
309 CrashFileManager fileManager = new CrashFileManager(mContext.getCacheDir ()); | 309 CrashFileManager fileManager = new CrashFileManager(mContext.getCacheDir ()); |
310 File logcatFile = fileManager.createNewTempFile("logcat.txt"); | 310 File logcatFile = fileManager.createNewTempFile("logcat.txt"); |
311 PrintWriter pWriter = null; | 311 PrintWriter pWriter = null; |
312 try { | 312 try { |
313 pWriter = new PrintWriter(new FileWriter(logcatFile)); | 313 pWriter = new PrintWriter(new FileWriter(logcatFile)); |
314 for (String ln : elidedLogcat) { | 314 for (String ln : elidedLogcat) { |
315 pWriter.println(ln); | 315 pWriter.println(ln); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 * {@link #CONSOLE_ELISION}. | 421 * {@link #CONSOLE_ELISION}. |
422 * | 422 * |
423 * @param original String potentially containing console messages. | 423 * @param original String potentially containing console messages. |
424 * @return String with elided console messages. | 424 * @return String with elided console messages. |
425 */ | 425 */ |
426 @VisibleForTesting | 426 @VisibleForTesting |
427 protected static String elideConsole(String original) { | 427 protected static String elideConsole(String original) { |
428 return CONSOLE_MSG.matcher(original).replaceAll(CONSOLE_ELISION); | 428 return CONSOLE_MSG.matcher(original).replaceAll(CONSOLE_ELISION); |
429 } | 429 } |
430 } | 430 } |
OLD | NEW |