Be more forgiving when parsing Art stacktraces

Bug: 122940268
Change-Id: I31ab90ac75187e4f7a117ffb4cb3b92a8f95fa8d
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/StackTrace.java b/src/test/java/com/android/tools/r8/naming/retrace/StackTrace.java
index dd8bc9c..0628653 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/StackTrace.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/StackTrace.java
@@ -157,17 +157,9 @@
     // \tat com.android.tools.r8.naming.retrace.Main.a(:150)
     // \tat com.android.tools.r8.naming.retrace.Main.a(:156)
     // \tat com.android.tools.r8.naming.retrace.Main.main(:162)
-    int last = stderrLines.size();
-    // Skip the bottom frame "dalvik.system.NativeStart.main" if present.
-    if (ToolHelper.getDexVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)
-        && stderrLines.get(last - 1).contains("dalvik.system.NativeStart.main")) {
-      last--;
-    }
-    // Take all lines from the bottom starting with "\tat ".
-    int first = last;
     // TODO(122940268): Remove test code when fixed.
     System.out.println("TOTAL STDERR LINES: " + stderrLines.size());
-    for (int i = 0; i < last; i++) {
+    for (int i = 0; i < stderrLines.size(); i++) {
       System.out.print("LINE " + i + ": " + stderrLines.get(i));
       if (stderrLines.get(i).length() > 3) {
         System.out.print(" (" + ((int) stderrLines.get(i).charAt(0)));
@@ -176,18 +168,21 @@
       } else {
         System.out.print(" (less than three chars)");
       }
-     if (stderrLines.get(i).startsWith(TAB_AT_PREFIX)) {
+      if (stderrLines.get(i).startsWith(TAB_AT_PREFIX)) {
         System.out.println(" IS STACKTRACE LINE");
       } else {
         System.out.println(" IS NOT STACKTRACE LINE");
       }
     }
-    while (first - 1 >= 0 && stderrLines.get(first - 1).startsWith(TAB_AT_PREFIX)) {
-      first--;
-    }
-    System.out.println("STACKTRACE LINES ARE " + first + " to " + (last - 1));
-    for (int i = first; i < last; i++) {
-      stackTraceLines.add(StackTraceLine.parse(stderrLines.get(i)));
+    for (int i = 0; i < stderrLines.size(); i++) {
+      String line = stderrLines.get(i);
+      // Find all lines starting with "\tat" except "dalvik.system.NativeStart.main" frame
+      // if present.
+      if (line.startsWith(TAB_AT_PREFIX)
+          && !(ToolHelper.getDexVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)
+              && line.contains("dalvik.system.NativeStart.main"))) {
+        stackTraceLines.add(StackTraceLine.parse(stderrLines.get(i)));
+      }
     }
     return new StackTrace(stackTraceLines, stderr);
   }
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/StackTraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/StackTraceTest.java
index e7ff8eb..c15bc2b 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/StackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/StackTraceTest.java
@@ -13,11 +13,18 @@
 
 public class StackTraceTest {
 
-  private static String oneLineStackTrace =
+  private static String lineOne =
       TAB_AT_PREFIX + "Test.main(Test.java:10)" + System.lineSeparator();
-  private static String twoLineStackTrace =
-      TAB_AT_PREFIX + "Test.a(Test.java:6)" + System.lineSeparator()
-          + TAB_AT_PREFIX + "Test.main(Test.java:10)" + System.lineSeparator();
+
+  private static String lineTwo = TAB_AT_PREFIX + "Test.a(Test.java:6)" + System.lineSeparator();
+
+  private static String randomArtLine =
+      "art W 26343 26343 art/runtime/base/mutex.cc:694] ConditionVariable::~ConditionVariable "
+          + "for Thread resumption condition variable called with 1 waiters."
+          + System.lineSeparator();
+
+  private static String oneLineStackTrace = lineOne;
+  private static String twoLineStackTrace = lineTwo + lineOne;
 
   private void testEquals(String stderr) {
     StackTrace stackTrace = StackTrace.extractFromJvm(stderr);
@@ -25,9 +32,7 @@
     assertEquals(stackTrace, StackTrace.extractFromJvm(stderr));
   }
 
-  @Test
-  public void testOneLine() {
-    StackTrace stackTrace = StackTrace.extractFromJvm(oneLineStackTrace);
+  private void checkOneLine(StackTrace stackTrace) {
     assertEquals(1, stackTrace.size());
     StackTraceLine stackTraceLine = stackTrace.get(0);
     assertEquals("Test", stackTraceLine.className);
@@ -38,9 +43,7 @@
     assertEquals(oneLineStackTrace, stackTrace.toStringWithPrefix(TAB_AT_PREFIX));
   }
 
-  @Test
-  public void testTwoLine() {
-    StackTrace stackTrace = StackTrace.extractFromJvm(twoLineStackTrace);
+  private void checkTwoLines(StackTrace stackTrace) {
     StackTraceLine stackTraceLine = stackTrace.get(0);
     assertEquals("Test", stackTraceLine.className);
     assertEquals("a", stackTraceLine.methodName);
@@ -57,8 +60,33 @@
   }
 
   @Test
+  public void testOneLineJvm() {
+    checkOneLine(StackTrace.extractFromJvm(oneLineStackTrace));
+  }
+
+  @Test
+  public void testOneLineArt() {
+    checkOneLine(StackTrace.extractFromArt(oneLineStackTrace));
+    checkOneLine(StackTrace.extractFromArt(oneLineStackTrace + randomArtLine));
+    checkOneLine(StackTrace.extractFromArt(randomArtLine + oneLineStackTrace));
+  }
+
+  @Test
+  public void testTwoLinesJvm() {
+    checkTwoLines(StackTrace.extractFromJvm(twoLineStackTrace));
+  }
+
+  @Test
+  public void testTwoLinesArt() {
+    checkTwoLines(StackTrace.extractFromJvm(twoLineStackTrace));
+    checkTwoLines(StackTrace.extractFromJvm(twoLineStackTrace + randomArtLine));
+    checkTwoLines(StackTrace.extractFromJvm(randomArtLine + twoLineStackTrace));
+    checkTwoLines(StackTrace.extractFromJvm(lineTwo + randomArtLine + lineOne));
+  }
+
+  @Test
   public void testEqualsOneLine() {
-    testEquals(oneLineStackTrace);
+    testEquals(lineOne);
   }
 
   @Test