diff --git a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/manager/impl/JdiManagerImpl.java b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/manager/impl/JdiManagerImpl.java index 85bdb55bd9..a049ec8291 100644 --- a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/manager/impl/JdiManagerImpl.java +++ b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/manager/impl/JdiManagerImpl.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.*; import java.util.concurrent.*; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.tuple.Pair; import com.sun.jdi.*; @@ -207,24 +208,25 @@ public class JdiManagerImpl implements JdiManager { @Override public CompletableFuture addVM(Connector cx, Map args) { - // TODO: Since this is making a blocking-on-the-network call, it should be supplyAsync - try { - curVM = connectVM(cx, args); - JdiEventHandler eventHandler = new JdiEventHandler(curVM, globalEventHandler); - eventHandler.start(); - eventHandler.setState(ThreadReference.THREAD_STATUS_NOT_STARTED, Causes.UNCLAIMED); - eventHandlers.put(curVM, eventHandler); - vms.put(curVM.name(), curVM); - connectors.put(curVM, cx); - } - catch (VMDisconnectedException e) { - System.out.println("Virtual Machine is disconnected."); - return CompletableFuture.failedFuture(e); - } - catch (Exception e) { - return CompletableFuture.failedFuture(e); - } - return CompletableFuture.completedFuture(curVM); + return CompletableFuture.supplyAsync(() -> { + try { + curVM = connectVM(cx, args); + JdiEventHandler eventHandler = new JdiEventHandler(curVM, globalEventHandler); + eventHandler.start(); + eventHandler.setState(ThreadReference.THREAD_STATUS_NOT_STARTED, Causes.UNCLAIMED); + eventHandlers.put(curVM, eventHandler); + vms.put(curVM.name(), curVM); + connectors.put(curVM, cx); + } + catch (VMDisconnectedException e) { + System.out.println("Virtual Machine is disconnected."); + return ExceptionUtils.rethrow(e); + } + catch (Exception e) { + return ExceptionUtils.rethrow(e); + } + return curVM; + }); } @Override diff --git a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelImpl.java b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelImpl.java index 18ea4455a5..2ca95eea33 100644 --- a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelImpl.java +++ b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelImpl.java @@ -71,6 +71,11 @@ public class JdiModelImpl extends AbstractDebuggerObjectModel { return completedRoot; } + @Override + public TargetObjectSchema getRootSchema() { + return ROOT_SCHEMA; + } + @Override public String getBrief() { return "JDI@" + Integer.toHexString(System.identityHashCode(this)); diff --git a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelTargetModuleContainer.java b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelTargetModuleContainer.java index a46bac36f7..307e4637c7 100644 --- a/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelTargetModuleContainer.java +++ b/Ghidra/Debug/Debugger-jpda/src/main/java/ghidra/dbg/jdi/model/JdiModelTargetModuleContainer.java @@ -106,13 +106,24 @@ public class JdiModelTargetModuleContainer extends JdiModelTargetObjectImpl } protected CompletableFuture doRefresh() { - Map map = new HashMap<>(); - List allModules = vm.vm.allModules(); - for (ModuleReference ref : allModules) { - map.put(JdiModelTargetModule.getUniqueId(ref), ref); - } - modulesByName.keySet().retainAll(map.keySet()); - return updateUsingModules(map); + return CompletableFuture.supplyAsync(() -> { + Map map = new HashMap<>(); + boolean available = vm.vm.canGetModuleInfo(); + if (!available) { + return map; + } + try { + List allModules = vm.vm.allModules(); + for (ModuleReference ref : allModules) { + map.put(JdiModelTargetModule.getUniqueId(ref), ref); + } + } + catch (UnsupportedOperationException e) { + Msg.error(this, "UnsupportedOperationException: " + e.getMessage()); + } + modulesByName.keySet().retainAll(map.keySet()); + return map; + }).thenCompose(this::updateUsingModules); } protected synchronized JdiModelTargetModule getTargetModule(ModuleReference module) {