protected void waitForLocation(String clsName, String methodName, long codeIndex) {
		try {
			waitForValuesPass("VMs[].Threads[main].Stack[0].Location.Method", methods -> {
				assertMatches("VMs[].Classes[" + clsName + "].Methods[" + methodName + "]",
					Unique.assertOne(methods).getChild());
			});
			waitForValuesPass("VMs[].Threads[main].Stack[0].Location.Index", indices -> {
				assertEquals(codeIndex, Unique.assertOne(indices).getValue());
			});
		}
		catch (AssertionError e) {
			TraceObjectValue locVal = Unique.assertAtMostOne(
				getValues("VMs[].Threads[main].Stack[0].Location"));
			if (locVal == null) {
				throw new AssertionError("Wrong location. Expected %s.%s:%d but was null"
						.formatted(clsName, methodName, codeIndex));
			}
			TraceObject loc = locVal.getChild();
			long snap = getMaxSnap();
			throw new AssertionError("Wrong location. Expected %s.%s:%d but was %s:%d"
					.formatted(clsName, methodName, codeIndex,
						loc.getAttribute(snap, "Method").getValue(),
						loc.getAttribute(snap, "Index").getValue()));
		}
	}
We know at this point the process should be terminated. Depending on how cleanly that
happened, the socket may or may not be closed. Do not assert/wait for it to close. Just
clean up by closing our end
Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/java/rmi/AbstractJavaTraceRmiTest.java