diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/gadp/DbgEngGadpServer.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/gadp/DbgEngGadpServer.java index 67fbfc60b8..0be3dd45fa 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/gadp/DbgEngGadpServer.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/gadp/DbgEngGadpServer.java @@ -22,6 +22,8 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import org.apache.commons.lang3.exception.ExceptionUtils; + import agent.dbgeng.gadp.impl.DbgEngGadpServerImpl; import ghidra.dbg.agent.AgentWindow; import ghidra.util.Msg; @@ -40,7 +42,13 @@ public interface DbgEngGadpServer extends AutoCloseable { * @throws InterruptedException */ public static void main(String[] args) throws Exception { - new DbgEngRunner().run(args); + try { + new DbgEngRunner().run(args); + } + catch (Throwable t) { + System.err.println(ExceptionUtils.getMessage(t)); + System.exit(1); + } } /** diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface1/DbgModelSelectableObject.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface1/DbgModelSelectableObject.java index 502e850ea8..88412bc4eb 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface1/DbgModelSelectableObject.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface1/DbgModelSelectableObject.java @@ -22,7 +22,13 @@ import agent.dbgeng.manager.DbgThread; import agent.dbgeng.manager.impl.DbgManagerImpl; import agent.dbgeng.model.iface2.*; import ghidra.dbg.target.TargetObject; +import ghidra.dbg.target.schema.TargetAttributeType; +import ghidra.dbg.target.schema.TargetObjectSchemaInfo; +@TargetObjectSchemaInfo( + name = "Selectable", + attributes = { + @TargetAttributeType(type = Void.class) }) public interface DbgModelSelectableObject extends DbgModelTargetObject { public default CompletableFuture setActive() { diff --git a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/DbgModelGadpServer.java b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/DbgModelGadpServer.java index cd18fa578b..fced63082e 100644 --- a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/DbgModelGadpServer.java +++ b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/DbgModelGadpServer.java @@ -19,6 +19,8 @@ import java.io.IOException; import java.net.SocketAddress; import java.util.concurrent.ExecutionException; +import org.apache.commons.lang3.exception.ExceptionUtils; + import agent.dbgeng.gadp.DbgEngGadpServer; import agent.dbgmodel.gadp.impl.DbgModelGadpServerImpl; import ghidra.dbg.agent.AgentWindow; @@ -75,7 +77,13 @@ public interface DbgModelGadpServer extends DbgEngGadpServer { * @throws InterruptedException */ public static void main(String[] args) throws Exception { - new DbgModelRunner().run(args); + try { + new DbgModelRunner().run(args); + } + catch (Throwable t) { + System.err.println(ExceptionUtils.getMessage(t)); + System.exit(1); + } } /** diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/gadp/GdbGadpServer.java b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/gadp/GdbGadpServer.java index 0727a81a69..5e157c993a 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/gadp/GdbGadpServer.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/gadp/GdbGadpServer.java @@ -22,13 +22,21 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import org.apache.commons.lang3.exception.ExceptionUtils; + import agent.gdb.gadp.impl.GdbGadpServerImpl; import ghidra.dbg.agent.AgentWindow; import ghidra.util.Msg; public interface GdbGadpServer extends AutoCloseable { public static void main(String[] args) throws Exception { - new Runner().run(args); + try { + new Runner().run(args); + } + catch (Throwable t) { + System.err.println(ExceptionUtils.getMessage(t)); + System.exit(1); + } } public static GdbGadpServer newInstance(SocketAddress addr) throws IOException { diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelSelectableObject.java b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelSelectableObject.java index 2e30a70cfb..1cee498889 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelSelectableObject.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelSelectableObject.java @@ -18,7 +18,13 @@ package agent.gdb.model.impl; import java.util.concurrent.CompletableFuture; import ghidra.dbg.target.TargetObject; +import ghidra.dbg.target.schema.TargetAttributeType; +import ghidra.dbg.target.schema.TargetObjectSchemaInfo; +@TargetObjectSchemaInfo( + name = "Selectable", + attributes = { + @TargetAttributeType(type = Void.class) }) interface GdbModelSelectableObject extends TargetObject { CompletableFuture setActive(); } diff --git a/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/server/AbstractGadpLocalDebuggerModelFactory.java b/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/server/AbstractGadpLocalDebuggerModelFactory.java index bfbbbe4928..3e0e19ede9 100644 --- a/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/server/AbstractGadpLocalDebuggerModelFactory.java +++ b/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/server/AbstractGadpLocalDebuggerModelFactory.java @@ -15,18 +15,18 @@ */ package ghidra.dbg.gadp.server; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.lang.ProcessBuilder.Redirect; +import java.io.*; import java.nio.channels.AsynchronousByteChannel; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import generic.concurrent.io.IOResult; +import generic.concurrent.io.ProcessConsumer; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.gadp.client.GadpClient; import ghidra.dbg.gadp.client.GadpTcpDebuggerModelFactory; -import ghidra.dbg.util.ConfigurableFactory.FactoryOption; import ghidra.util.Msg; public abstract class AbstractGadpLocalDebuggerModelFactory implements DebuggerModelFactory { @@ -108,9 +108,13 @@ public abstract class AbstractGadpLocalDebuggerModelFactory implements DebuggerM } completeCommandLine(cmd); builder.command(cmd); - builder.redirectError(Redirect.INHERIT); + //builder.redirectError(Redirect.INHERIT); process = builder.start(); + + InputStream errorStream = process.getErrorStream(); + Future errorFuture = ProcessConsumer.consume(errorStream); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; @@ -124,9 +128,19 @@ public abstract class AbstractGadpLocalDebuggerModelFactory implements DebuggerM ready.complete(null); } } + if (!ready.isDone()) { - ready.completeExceptionally( - new RuntimeException("Agent terminated unexpectedly")); + IOResult errorResult = errorFuture.get(); + String errorMessage = errorResult.getOutputAsString(); + if (errorMessage != null) { + ready.completeExceptionally( + new RuntimeException("Agent terminated with error: " + errorMessage)); + } + else { + ready.completeExceptionally( + new RuntimeException("Agent terminated unexpectedly")); + } + } } catch (Throwable e) { diff --git a/Ghidra/Framework/Generic/src/main/java/generic/concurrent/io/IOResult.java b/Ghidra/Framework/Generic/src/main/java/generic/concurrent/io/IOResult.java index 6070296c66..9a3170f9b6 100644 --- a/Ghidra/Framework/Generic/src/main/java/generic/concurrent/io/IOResult.java +++ b/Ghidra/Framework/Generic/src/main/java/generic/concurrent/io/IOResult.java @@ -32,7 +32,7 @@ public class IOResult implements Runnable { public static final String THREAD_POOL_NAME = "I/O Thread Pool"; - private List outputLines = new ArrayList(); + private List outputLines = new ArrayList<>(); private BufferedReader commandOutput; private final Throwable inception; private Consumer consumer = Dummy.consumer(); @@ -53,7 +53,7 @@ public class IOResult implements Runnable { public String getOutputAsString() { StringBuilder buffy = new StringBuilder(); for (String line : outputLines) { - buffy.append(line); + buffy.append(line).append("\n"); } return buffy.toString(); }