Skip to content

Commit

Permalink
Add some extra info when terminate fails in tests
Browse files Browse the repository at this point in the history
On GitHub I see fails in resume[gdb] (org.eclipse.cdt.tests.dsf.gdb.tests.MIRunControlTest)

with this output:

```
Terminate failed
org.eclipse.debug.core.DebugException: Terminate failed
	at org.eclipse.debug.core.Launch.terminate(Launch.java:300)
	at org.eclipse.cdt.dsf.gdb.launching.GdbLaunch.terminate(GdbLaunch.java:313)
	at org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase.doAfterTest(BaseTestCase.java:662)
	at org.eclipse.cdt.tests.dsf.gdb.tests.MIRunControlTest.doAfterTest(MIRunControlTest.java:133)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.RunAfters.invokeMethod(RunAfters.java:46)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:299)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:293)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Contains: Terminate failed
Contains: Terminate failed
790,475 "resume[gdb]" requesting gdb. Launched gdb 15.0.50.20240403.
```

which is insufficient to diagnose what is happening.

Part of #816
  • Loading branch information
jonahgraham committed Jan 22, 2025
1 parent 0faf90e commit ea45079
Showing 1 changed file with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -54,10 +57,12 @@
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
Expand All @@ -66,6 +71,8 @@
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.RuntimeProcess;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.junit.After;
import org.junit.AfterClass;
Expand Down Expand Up @@ -659,7 +666,74 @@ protected void assertLaunchTerminates(GdbLaunch launch, boolean terminate) throw
@After
public void doAfterTest() throws Exception {
if (fLaunch != null) {
fLaunch.terminate();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(byteArrayOutputStream, true, "UTF-8");
IProcess[] processes = fLaunch.getProcesses();

out.println("Processes: " + Arrays.toString(processes));
for (IProcess process : processes) {
out.println("Process: " + process);
if (process instanceof RuntimeProcess runtimeProcess) {
Field field = RuntimeProcess.class.getDeclaredField("fProcess");
field.trySetAccessible();
Process javaProcess = (Process) field.get(runtimeProcess);
out.println("javaProcess: " + javaProcess);
try {
List<ProcessHandle> descendants = javaProcess.descendants().collect(Collectors.toList());
out.println("descendants: " + descendants);
} catch (UnsupportedOperationException e) {
out.println("descendants unsupported");
}
} else {
out.println("Class: " + process.getClass());
}
if (process.isTerminated()) {
out.println("isTerminated: true");
out.println("exitValue: " + process.getExitValue());
} else {
out.println("isTerminated: false");
}
}
boolean failed = false;
for (IProcess process : processes) {
out.println("TERMINATING");
out.println("Process: " + process);

if (process instanceof RuntimeProcess runtimeProcess) {
Field field = RuntimeProcess.class.getDeclaredField("fProcess");
field.trySetAccessible();
Process javaProcess = (Process) field.get(runtimeProcess);
if (javaProcess == null) {
out.println("javaProcess: null");
} else {
javaProcess.destroy();
out.println("WAITING");
boolean waitFor = javaProcess.waitFor(1, TimeUnit.SECONDS);
out.println("waitFor: " + waitFor);
if (waitFor) {
out.println("exitValue: " + javaProcess.exitValue());
} else {
failed = true;
}
}
}
}
String info = byteArrayOutputStream.toString("UTF-8");
try {
fLaunch.terminate();
if (failed) {
throw new RuntimeException("Failed to terminate\ninfo:\n" + info);
}
} catch (DebugException e) {
IStatus status = e.getStatus();
if (status != null) {
String statusString = status.toString();
throw new RuntimeException("Received debug exception with: " + statusString + "\ninfo:\n" + info,
e);
} else {
throw new RuntimeException("Received debug with no status\ninfo:\n" + info, e);
}
}
assertLaunchTerminates();
fLaunch = null;
}
Expand Down

0 comments on commit ea45079

Please sign in to comment.