From 808c20ab7ffcbe1f9e4646c14a7ed62689a64f33 Mon Sep 17 00:00:00 2001
From: Dan <46821332+nsadeveloper789@users.noreply.github.com>
Date: Wed, 21 Apr 2021 16:54:30 -0400
Subject: [PATCH] GP-380: Better quick launch using opinions and offers.
---
.../DbgEngInJvmDebuggerModelFactory.java | 10 +-
.../DbgModelInJvmDebuggerModelFactory.java | 10 +-
.../main/java/agent/gdb/GdbCompatibility.java | 51 ++++
.../gdb/GdbInJvmDebuggerModelFactory.java | 9 +-
.../gdb/GdbOverSshDebuggerModelFactory.java | 7 +-
.../gadp/GdbLocalDebuggerModelFactory.java | 34 +--
...AbstractGadpLocalDebuggerModelFactory.java | 5 +-
.../dbg/jdi/JdiDebuggerModelFactory.java | 10 +-
.../Debugger/data/ExtensionPoint.manifest | 1 +
.../help/help/topics/Debugger/Debugger.html | 4 +-
.../DebuggerModelServicePlugin.html | 26 +-
.../core/debug/gui/DebuggerResources.java | 18 +-
.../DebuggerMethodInvocationDialog.java | 12 +-
.../gui/target/DebuggerConnectDialog.java | 7 +-
.../DbgDebuggerProgramLaunchOpinion.java | 167 +++++++++++
.../GdbDebuggerProgramLaunchOpinion.java | 144 +++++++++
.../model/DebuggerModelServicePlugin.java | 46 ++-
.../DebuggerModelServiceProxyPlugin.java | 263 ++++++++++++-----
.../AbstractDebuggerProgramLaunchOffer.java | 279 ++++++++++++++++++
.../launch/DebuggerProgramLaunchOffer.java | 109 +++++++
.../launch/DebuggerProgramLaunchOpinion.java | 28 ++
.../app/services/DebuggerModelService.java | 49 ++-
.../model/DebuggerModelServiceTest.java | 33 +--
.../TestDebuggerProgramLaunchOpinion.java | 67 +++++
.../java/ghidra/dbg/DebuggerObjectModel.java | 16 -
.../ghidra/dbg/LocalDebuggerModelFactory.java | 44 ---
.../model/TestLocalDebuggerModelFactory.java | 44 ---
.../util/database/UndoableTransaction.java | 27 ++
28 files changed, 1210 insertions(+), 310 deletions(-)
create mode 100644 Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/GdbCompatibility.java
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/DbgDebuggerProgramLaunchOpinion.java
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/GdbDebuggerProgramLaunchOpinion.java
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOffer.java
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOpinion.java
create mode 100644 Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java
delete mode 100644 Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/LocalDebuggerModelFactory.java
delete mode 100644 Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestLocalDebuggerModelFactory.java
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/DbgEngInJvmDebuggerModelFactory.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/DbgEngInJvmDebuggerModelFactory.java
index 676275268b..a01b4b4334 100644
--- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/DbgEngInJvmDebuggerModelFactory.java
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/DbgEngInJvmDebuggerModelFactory.java
@@ -18,21 +18,19 @@ package agent.dbgeng;
import java.util.concurrent.CompletableFuture;
import agent.dbgeng.model.impl.DbgModelImpl;
+import ghidra.dbg.DebuggerModelFactory;
import ghidra.dbg.DebuggerObjectModel;
-import ghidra.dbg.LocalDebuggerModelFactory;
import ghidra.dbg.util.ConfigurableFactory.FactoryDescription;
-import ghidra.util.classfinder.ExtensionPointProperties;
/**
- * Note this is in the testing source because it's not meant to be shipped in
- * the release.... That may change if it proves stable, though, no?
+ * Note this is in the testing source because it's not meant to be shipped in the release.... That
+ * may change if it proves stable, though, no?
*/
@FactoryDescription( //
brief = "IN-VM MS dbgeng local debugger", //
htmlDetails = "Launch a dbgeng session in this same JVM" //
)
-@ExtensionPointProperties(priority = 80)
-public class DbgEngInJvmDebuggerModelFactory implements LocalDebuggerModelFactory {
+public class DbgEngInJvmDebuggerModelFactory implements DebuggerModelFactory {
// TODO remoteTransport option?
diff --git a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/DbgModelInJvmDebuggerModelFactory.java b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/DbgModelInJvmDebuggerModelFactory.java
index 2c2b22be0c..0cee6215b9 100644
--- a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/DbgModelInJvmDebuggerModelFactory.java
+++ b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/DbgModelInJvmDebuggerModelFactory.java
@@ -18,21 +18,19 @@ package agent.dbgmodel;
import java.util.concurrent.CompletableFuture;
import agent.dbgmodel.model.impl.DbgModel2Impl;
+import ghidra.dbg.DebuggerModelFactory;
import ghidra.dbg.DebuggerObjectModel;
-import ghidra.dbg.LocalDebuggerModelFactory;
import ghidra.dbg.util.ConfigurableFactory.FactoryDescription;
-import ghidra.util.classfinder.ExtensionPointProperties;
/**
* Note this is in the testing source because it's not meant to be shipped in the release.... That
* may change if it proves stable, though, no?
*/
@FactoryDescription( //
- brief = "IN-VM MS dbgmodel local debugger", //
- htmlDetails = "Launch a dbgmodel session in this same JVM" //
+ brief = "IN-VM MS dbgmodel local debugger", //
+ htmlDetails = "Launch a dbgmodel session in this same JVM" //
)
-@ExtensionPointProperties(priority = 70)
-public class DbgModelInJvmDebuggerModelFactory implements LocalDebuggerModelFactory {
+public class DbgModelInJvmDebuggerModelFactory implements DebuggerModelFactory {
@Override
public CompletableFuture extends DebuggerObjectModel> build() {
diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/GdbCompatibility.java b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/GdbCompatibility.java
new file mode 100644
index 0000000000..8570e20d61
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/GdbCompatibility.java
@@ -0,0 +1,51 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package agent.gdb;
+
+import java.io.IOException;
+import java.lang.ProcessBuilder.Redirect;
+import java.util.*;
+
+import ghidra.dbg.util.ShellUtils;
+
+public enum GdbCompatibility {
+ INSTANCE;
+
+ public static boolean checkGdbPresent(String path) {
+ try {
+ ProcessBuilder builder = new ProcessBuilder(path, "--version");
+ builder.redirectError(Redirect.INHERIT);
+ builder.redirectOutput(Redirect.INHERIT);
+ @SuppressWarnings("unused")
+ Process gdb = builder.start();
+ // TODO: Once supported versions are decided, check the version.
+ return true;
+ }
+ catch (IOException e) {
+ return false;
+ }
+ }
+
+ private final Map This action is available whenever a program is opened, and the current program indicates an
- "executable path" that exists on the local file system and is marked executable by the host
- operating system. It will launch a suitable connection for debugging local applications, and
- then run the current program in that debugger. If This group of actions is available whenever there exists a debug launcher that knows how to
+ run the current program. Various launchers may all make offers to run the current program, each
+ of which is presented as a item in this group. Not all offers are guaranteed to work. For
+ example, an offer to launch the program remotely via SSH depends on the host's availability and
+ the user's credentials. The offers are ordered by most recent activation. The most recent offer
+ used is the default one-click launcher for the current program. Each launcher may check various
+ conditions before making an offer. Most commonly, it will check that there is a suitable
+ debugger for the current program's architecture (language) on the local system, that the
+ program's original executable image still exists on disk, and that the user has permission to
+ execute it. A launcher may take any arbitrary action to run the program. Most commonly, it
+ starts a new connection suitable for the target, and then launches the program on that
+ connection. If Record
Automatically is enabled, this will provide a one-click action to debug the current
program. This is similar to the Quick Launch
- action in the Commands and Objects window, except this one creates a new connection. Debug Program
-
The launch offers are presented in two places. First, they are listed as drop-down items + from the "Debug Program" action in the main toolbar. When activated here, there are typically + no further prompts. One notable exception is SSH, where authentication may be required. Second, + they are listed under the
menu. When + activated here, the launcher should prompt for arguments. The chosen arguments are saved as the + default for future launches of the current program.
+ * It is not sufficient to simply take the defaults specified in the parameters. This must
+ * populate the arguments necessary to launch the requested program.
+ *
+ * @param params the parameters
+ * @return the default arguments
+ */
+ protected abstract Map
+ * If there are no saved "last used" arguments, then this will return the defaults. If there are
+ * saved arguments, but they cannot be loaded, then this will behave differently depending on
+ * whether the user will be confirming the arguments. If there will be no prompt/confirmation,
+ * then this method must throw an exception in order to avoid launching with defaults, when the
+ * user may be expecting a customized launch. If there will be a prompt, then this may safely
+ * return the defaults, since the user will be given a chance to correct them.
+ *
+ * @param params the parameters of the model's launcher
+ * @param forPrompt true if the user will be confirming the arguments
+ * @return the loaded arguments, or defaults
+ */
+ protected Map
+ * This should either call {@link #promptLauncherArgs(Map))} or
+ * {@link #loadLastLauncherArgs(Map, boolean))}. Note if choosing the latter, the user will not
+ * be prompted to confirm.
+ *
+ * @param params the parameters of the model's launcher
+ * @return the chosen arguments
+ */
+ protected Map