GP-0: Fixed timeout issue in GDB connector

This commit is contained in:
Dan 2022-02-01 11:08:38 -05:00
parent c395c3d7ca
commit 50fae841b8

View file

@ -72,6 +72,7 @@ import sun.misc.SignalHandler;
* event is processed using a {@link HandlerMap}. * event is processed using a {@link HandlerMap}.
*/ */
public class GdbManagerImpl implements GdbManager { public class GdbManagerImpl implements GdbManager {
private static final int TIMEOUT_SEC = 10;
private static final String GDB_IS_TERMINATING = "GDB is terminating"; private static final String GDB_IS_TERMINATING = "GDB is terminating";
public static final int MAX_CMD_LEN = 4094; // Account for longest possible line end public static final int MAX_CMD_LEN = 4094; // Account for longest possible line end
@ -126,7 +127,7 @@ public class GdbManagerImpl implements GdbManager {
} }
try { try {
String line; String line;
while (isAlive() && null != (line = reader.readLine())) { while (GdbManagerImpl.this.isAlive() && null != (line = reader.readLine())) {
String l = line; String l = line;
if (interpreter == null) { if (interpreter == null) {
if (l.startsWith("=") || l.startsWith("~")) { if (l.startsWith("=") || l.startsWith("~")) {
@ -624,6 +625,16 @@ public class GdbManagerImpl implements GdbManager {
this.newLine = newLine; this.newLine = newLine;
} }
protected void waitCheckExit(CompletableFuture<?> future)
throws InterruptedException, ExecutionException, TimeoutException, IOException {
CompletableFuture.anyOf(future, state.waitValue(GdbState.EXIT))
.get(TIMEOUT_SEC, TimeUnit.SECONDS);
if (state.get() == GdbState.EXIT) {
throw new IOException(
"GDB terminated early or could not be executed. Check your command line.");
}
}
@Override @Override
public void start(String gdbCmd, String... args) throws IOException { public void start(String gdbCmd, String... args) throws IOException {
List<String> fullargs = new ArrayList<>(); List<String> fullargs = new ArrayList<>();
@ -642,16 +653,12 @@ public class GdbManagerImpl implements GdbManager {
iniThread.start(); iniThread.start();
try { try {
CompletableFuture.anyOf(iniThread.hasWriter, state.waitValue(GdbState.EXIT)) waitCheckExit(iniThread.hasWriter);
.get(10, TimeUnit.SECONDS);
} }
catch (InterruptedException | ExecutionException | TimeoutException e) { catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new IOException( throw new IOException(
"Could not detect GDB's interpreter mode. Try " + gdbCmd + " -i mi2"); "Could not detect GDB's interpreter mode. Try " + gdbCmd + " -i mi2");
} }
if (state.get() == GdbState.EXIT) {
throw new IOException("GDB terminated before first prompt");
}
switch (iniThread.interpreter) { switch (iniThread.interpreter) {
case CLI: case CLI:
Pty mi2Pty = ptyFactory.openpty(); Pty mi2Pty = ptyFactory.openpty();
@ -678,7 +685,7 @@ public class GdbManagerImpl implements GdbManager {
mi2Thread.setName("GDB Read MI2"); mi2Thread.setName("GDB Read MI2");
mi2Thread.start(); mi2Thread.start();
try { try {
mi2Thread.hasWriter.get(10, TimeUnit.SECONDS); waitCheckExit(mi2Thread.hasWriter);
} }
catch (InterruptedException | ExecutionException | TimeoutException e) { catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new IOException( throw new IOException(