Add a new debug test with a bad local variable scope
- Add support into test framework allowing to set breakpoint
on a specific line.
Bug: 69093793
Change-Id: Iddc672d6613dde305d2337f1e4fc6dd359fdfbbb
diff --git a/src/test/debugTestResources/Locals.java b/src/test/debugTestResources/Locals.java
index 71f2a66..e32f2ca 100644
--- a/src/test/debugTestResources/Locals.java
+++ b/src/test/debugTestResources/Locals.java
@@ -353,6 +353,18 @@
return c;
}
+ public static void localVisibilityIntoLoop(double B[][], double A[][]) {
+ int i;
+ int length = 1;
+ for (i = 0; i < length; i++) {
+ double Bi[] = B[i];
+ double Ai[] = A[i];
+ for (int j = 0; j < 1; j += 4) {
+ Bi[j] = Ai[j];
+ }
+ }
+ }
+
public static void main(String[] args) {
noLocals();
unusedLocals();
@@ -377,5 +389,6 @@
System.out.println(localConstantBis(true));
System.out.println(localTriggeringCSE());
System.out.println(intAddition(1, 2, 6));
+ localVisibilityIntoLoop(new double[1][1], new double[1][1]);
}
}
diff --git a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
index 740d4e3..8db3bf8 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OffOrAuto;
import com.google.common.collect.ImmutableList;
+import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList;
import java.io.File;
@@ -121,6 +122,8 @@
private static final DexCompilerKind DEX_COMPILER_KIND = DexCompilerKind.D8;
+ private static final int FIRST_LINE = -1;
+
// Set to true to enable verbose logs
private static final boolean DEBUG_TESTS = false;
@@ -410,9 +413,18 @@
return breakpoint(className, methodName, null);
}
+ protected final JUnit3Wrapper.Command breakpoint(String className, String methodName, int line) {
+ return breakpoint(className, methodName, null, line);
+ }
+
protected final JUnit3Wrapper.Command breakpoint(String className, String methodName,
String methodSignature) {
- return new JUnit3Wrapper.Command.BreakpointCommand(className, methodName, methodSignature);
+ return breakpoint(className, methodName, methodSignature, FIRST_LINE);
+ }
+
+ protected final JUnit3Wrapper.Command breakpoint(String className, String methodName,
+ String methodSignature, int line) {
+ return new JUnit3Wrapper.Command.BreakpointCommand(className, methodName, methodSignature, line);
}
protected final JUnit3Wrapper.Command stepOver() {
@@ -1425,18 +1437,30 @@
setState(State.WaitForEvent);
}
- private long getMethodFirstCodeIndex(long classId, long breakpointMethodId) {
+ private LongList getMethodCodeIndex(long classId, long breakpointMethodId, int lineToSearch) {
+ LongList pcs = new LongArrayList();
ReplyPacket replyPacket = getMirror().getLineTable(classId, breakpointMethodId);
checkReplyPacket(replyPacket, "Failed to get method line table");
- replyPacket.getNextValueAsLong(); // start
- replyPacket.getNextValueAsLong(); // end
+ long start = replyPacket.getNextValueAsLong(); // start
+ long end = replyPacket.getNextValueAsLong(); // end
int linesCount = replyPacket.getNextValueAsInt();
if (linesCount == 0) {
- return -1;
+ pcs.add(-1L);
} else {
- // Read only the 1st line because code indices are in ascending order
- return replyPacket.getNextValueAsLong();
+ if (lineToSearch == FIRST_LINE) {
+ // Read only the 1st line because code indices are in ascending order
+ pcs.add(replyPacket.getNextValueAsLong());
+ } else {
+ for (int entry = 0; entry < linesCount; entry++) {
+ long pc = replyPacket.getNextValueAsLong();
+ long lineNumber = replyPacket.getNextValueAsInt();
+ if (lineNumber == lineToSearch) {
+ pcs.add(pc);
+ }
+ }
+ }
}
+ return pcs;
}
//
@@ -1465,14 +1489,16 @@
private final String methodName;
private final String methodSignature;
private boolean requestedClassPrepare = false;
+ private int line;
public BreakpointCommand(String className, String methodName,
- String methodSignature) {
+ String methodSignature, int line) {
assert className != null;
assert methodName != null;
this.className = className;
this.methodName = methodName;
this.methodSignature = methodSignature;
+ this.line = line;
}
@Override
@@ -1513,13 +1539,15 @@
testBase.translator.getObfuscatedMethodName(className, methodName, methodSignature);
long breakpointMethodId =
findMethod(mirror, classId, obfuscatedMethodName, methodSignature);
- long index = testBase.getMethodFirstCodeIndex(classId, breakpointMethodId);
- Assert.assertTrue("No code in method", index >= 0);
- ReplyPacket replyPacket = testBase.getMirror().setBreakpoint(
- new Location(typeTag, classId, breakpointMethodId, index), SuspendPolicy.ALL);
- assert replyPacket.getErrorCode() == Error.NONE;
- int breakpointId = replyPacket.getNextValueAsInt();
- testBase.events.put(Integer.valueOf(breakpointId), new DefaultEventHandler());
+ LongList pcs = testBase.getMethodCodeIndex(classId, breakpointMethodId, line);
+ for (long pc : pcs) {
+ Assert.assertTrue("No code in method", pc >= 0);
+ ReplyPacket replyPacket = testBase.getMirror().setBreakpoint(
+ new Location(typeTag, classId, breakpointMethodId, pc), SuspendPolicy.ALL);
+ assert replyPacket.getErrorCode() == Error.NONE;
+ int breakpointId = replyPacket.getNextValueAsInt();
+ testBase.events.put(Integer.valueOf(breakpointId), new DefaultEventHandler());
+ }
}
}
@@ -1575,6 +1603,10 @@
sb.append(className);
sb.append(" method=");
sb.append(methodName);
+ sb.append(" signature=");
+ sb.append(methodSignature);
+ sb.append(" line=");
+ sb.append(line);
return sb.toString();
}
}
diff --git a/src/test/java/com/android/tools/r8/debug/LocalsTest.java b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
index 1ef7f3e..b2c551b 100644
--- a/src/test/java/com/android/tools/r8/debug/LocalsTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
@@ -3,12 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.debug;
+import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.FrameInspector;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants.Tag;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -16,6 +20,8 @@
*/
public class LocalsTest extends DebugTestBase {
+ private static final boolean RUN_JAVA = false;
+
public static final String SOURCE_FILE = "Locals.java";
@Test
@@ -680,4 +686,47 @@
checkLocal("c", Value.createInt(11)),
run());
}
+
+ @Test
+ @Ignore("b/69093793")
+ public void testLocalVisibilityIntoLoop() throws Throwable {
+ final String className = "Locals";
+ final String methodName = "localVisibilityIntoLoop";
+
+ List<Command> commands = new ArrayList<>();
+ commands.add(breakpoint(className, methodName, 359));
+ commands.add(run());
+ commands.add(checkMethod(className, methodName));
+ commands.add(checkLine(SOURCE_FILE, 359));
+ commands.add(checkNoLocal("Ai"));
+ commands.add(checkNoLocal("Bi"));
+ commands.add(checkNoLocal("i"));
+ commands.add(stepOver());
+ commands.add(checkMethod(className, methodName));
+ commands.add(checkLine(SOURCE_FILE, 360));
+ commands.add(checkNoLocal("Ai"));
+ commands.add(checkNoLocal("Bi"));
+ commands.add(checkLocal("i", Value.createInt(0)));
+ commands.add(stepOver());
+ commands.add(checkMethod(className, methodName));
+ commands.add(checkLine(SOURCE_FILE, 361));
+ commands.add(checkNoLocal("Ai"));
+ commands.add(checkLocal("Bi"));
+ commands.add(checkLocal("i", Value.createInt(0)));
+ commands.add(stepOver());
+ commands.add(checkMethod(className, methodName));
+ commands.add(checkLine(SOURCE_FILE, 362));
+ commands.add(checkLocal("Ai"));
+ commands.add(checkLocal("Bi"));
+ commands.add(checkLocal("i", Value.createInt(0)));
+ commands.add(run());
+ commands.add(checkMethod(className, methodName));
+ commands.add(checkLine(SOURCE_FILE, 359));
+ commands.add(checkNoLocal("Ai"));
+ commands.add(checkNoLocal("Bi"));
+ commands.add(checkLocal("i", Value.createInt(0)));
+ commands.add(run());
+
+ runDebugTest(getDebuggeeDexD8OrCf(RUN_JAVA), className, commands);
+ }
}