Skip to content

Commit d55b7e9

Browse files
committedJan 13, 2023
Merge remote-tracking branch
'origin/GP-2968_d-millar_param_errors--SQUASHED' (NationalSecurityAgency#4791)
2 parents f930701 + c43351d commit d55b7e9

File tree

13 files changed

+159
-92
lines changed

13 files changed

+159
-92
lines changed
 

‎Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/impl/DbgManagerImpl.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,9 +1382,8 @@ public CompletableFuture<Void> launch(Map<String, ?> map) {
13821382
BitmaskSet<DebugVerifierFlags> vf =
13831383
new BitmaskSet<DebugVerifierFlags>(DebugVerifierFlags.class,
13841384
vfVal == null ? 0 : vfVal);
1385-
execute(new DbgLaunchProcessCommand(this, args,
1386-
initDir, env, cf, ef, vf));
1387-
return AsyncUtils.NIL;
1385+
return execute(new DbgLaunchProcessCommand(this, args,
1386+
initDir, env, cf, ef, vf)).thenApply(__ -> null);
13881387
}
13891388

13901389
public CompletableFuture<?> openFile(Map<String, ?> args) {

‎Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetContinuationOptionImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public CompletableFuture<Void> setOption(int ordinal) {
8282
public void setAttributes() {
8383
changeAttributes(List.of(), List.of(), Map.of( //
8484
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionCont.description, //
85-
VALUE_ATTRIBUTE_NAME, optionCont, //
85+
VALUE_ATTRIBUTE_NAME, optionCont.val, //
8686
ENABLED_ATTRIBUTE_NAME,
8787
optionCont.equals(DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED)),
8888
"Refreshed");

‎Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetExecutionOptionImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public CompletableFuture<Void> setOption(int ordinal) {
8383
public void setAttributes() {
8484
changeAttributes(List.of(), List.of(), Map.of( //
8585
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionExc.description, //
86-
VALUE_ATTRIBUTE_NAME, optionExc, //
86+
VALUE_ATTRIBUTE_NAME, optionExc.val, //
8787
ENABLED_ATTRIBUTE_NAME,
8888
optionExc.equals(DebugFilterExecutionOption.DEBUG_FILTER_BREAK)), "Refreshed");
8989
}

‎Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetProcessLaunchConnectorImpl.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ protected Map<String, ParameterDescription<?>> computeParameters() {
7878
map.put("cf", cf);
7979
map.put("ef", ef);
8080
map.put("vf", vf);
81+
// Innocuous comment: up-up-down-down-left-right-left-right-B-A
8182
return map;
8283
}
8384

@@ -91,11 +92,4 @@ public CompletableFuture<Void> launch(Map<String, ?> args) {
9192
return getManager().launch(args);
9293
}
9394

94-
// public CompletableFuture<Void> launch(List<String> args) {
95-
// return AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
96-
// getManager().launch(args).handle(seq::nextIgnore);
97-
// }).finish().exceptionally((exc) -> {
98-
// throw new DebuggerUserException("Launch failed for " + args);
99-
// });
100-
// }
10195
}

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/DebuggerObjectsProvider.java

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import ghidra.dbg.target.*;
6060
import ghidra.dbg.target.TargetConsole.Channel;
6161
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
62-
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
6362
import ghidra.dbg.target.TargetMethod.ParameterDescription;
6463
import ghidra.dbg.target.TargetSteppable.TargetStepKind;
6564
import ghidra.dbg.util.DebuggerCallbackReorderer;
@@ -1335,38 +1334,32 @@ public void performQuickLaunch(ActionContext context) {
13351334
if (currentProgram == null) {
13361335
return;
13371336
}
1338-
performAction(context, true, TargetLauncher.class, launcher -> {
1339-
// TODO: A generic or pluggable way of deriving the launch arguments
1340-
return launcher.launch(Map.of(
1341-
TargetCmdLineLauncher.CMDLINE_ARGS_NAME, currentProgram.getExecutablePath()));
1342-
}, "Couldn't launch");
1337+
performLaunchAction(context, false);
13431338
}
13441339

13451340
public void performLaunch(ActionContext context) {
1346-
performAction(context, true, TargetLauncher.class, launcher -> {
1341+
performLaunchAction(context, true);
1342+
}
13471343

1348-
Map<String, ?> args = launchOffer.getLauncherArgs(launcher, true);
1349-
if (args == null) {
1350-
// Cancelled
1351-
return AsyncUtils.NIL;
1352-
}
1353-
return launcher.launch(args);
1354-
/*
1355-
String argsKey = TargetCmdLineLauncher.CMDLINE_ARGS_NAME;
1356-
String path = (currentProgram != null) ? currentProgram.getExecutablePath() : null;
1357-
launchDialog.setCurrentContext(path);
1358-
String cmdlineArgs = launchDialog.getMemorizedArgument(argsKey, String.class);
1359-
if (cmdlineArgs == null) {
1360-
cmdlineArgs = path;
1361-
launchDialog.setMemorizedArgument(argsKey, String.class,
1362-
cmdlineArgs);
1363-
}
1364-
Map<String, ?> args = launchDialog.promptArguments(launcher.getParameters());
1365-
if (args == null) {
1366-
return AsyncUtils.NIL;
1367-
}
1368-
return launcher.launch(args);
1369-
*/
1344+
private void performLaunchAction(ActionContext context, boolean p) {
1345+
performAction(context, true, TargetLauncher.class, launcher -> {
1346+
var locals = new Object() {
1347+
boolean prompt = p;
1348+
};
1349+
return AsyncUtils.loop(TypeSpec.VOID, (loop) -> {
1350+
Map<String, ?> args = launchOffer.getLauncherArgs(launcher, locals.prompt);
1351+
if (args == null) {
1352+
// Cancelled
1353+
loop.exit();
1354+
}
1355+
else {
1356+
launcher.launch(args).thenAccept(loop::exit).exceptionally(ex -> {
1357+
loop.repeat();
1358+
return null;
1359+
});
1360+
}
1361+
locals.prompt = true;
1362+
});
13701363
}, "Couldn't launch");
13711364
}
13721365

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/DebuggerMethodInvocationDialog.java

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
import java.awt.FlowLayout;
2020
import java.awt.event.ActionEvent;
2121
import java.beans.*;
22-
import java.util.HashMap;
23-
import java.util.Map;
24-
import java.util.stream.Collectors;
22+
import java.util.*;
2523

2624
import javax.swing.*;
2725
import javax.swing.border.EmptyBorder;
@@ -32,6 +30,7 @@
3230
import org.jdom.Element;
3331

3432
import docking.DialogComponentProvider;
33+
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
3534
import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils;
3635
import ghidra.dbg.target.TargetMethod;
3736
import ghidra.dbg.target.TargetMethod.ParameterDescription;
@@ -92,6 +91,8 @@ public Class<?> getType() {
9291
private PairLayout layout;
9392

9493
protected JButton invokeButton;
94+
protected JButton resetButton;
95+
protected boolean resetRequested;
9596

9697
private final PluginTool tool;
9798
private Map<String, ParameterDescription<?>> parameters;
@@ -105,7 +106,7 @@ public DebuggerMethodInvocationDialog(PluginTool tool, String title, String butt
105106
super(title, true, false, true, false);
106107
this.tool = tool;
107108

108-
populateComponents(buttonText, buttonIcon);
109+
populateComponents(buttonText, buttonIcon, "Reset", DebuggerResources.ICON_REFRESH);
109110
setRememberSize(false);
110111
}
111112

@@ -126,7 +127,8 @@ public void setParameters(Map<String, ParameterDescription<?>> parameterMap) {
126127
populateOptions();
127128
}
128129

129-
private void populateComponents(String buttonText, Icon buttonIcon) {
130+
private void populateComponents(String buttonText, Icon buttonIcon,
131+
String resetText, Icon resetIcon) {
130132
panel = new JPanel(new BorderLayout());
131133
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
132134

@@ -144,19 +146,31 @@ private void populateComponents(String buttonText, Icon buttonIcon) {
144146

145147
invokeButton = new JButton(buttonText, buttonIcon);
146148
addButton(invokeButton);
149+
resetButton = new JButton(resetText, resetIcon);
150+
addButton(resetButton);
147151
addCancelButton();
148152

149153
invokeButton.addActionListener(this::invoke);
154+
resetButton.addActionListener(this::reset);
155+
resetRequested = false;
150156
}
151157

152158
@Override
153159
protected void cancelCallback() {
154160
this.arguments = null;
161+
this.resetRequested = false;
155162
close();
156163
}
157164

158165
private void invoke(ActionEvent evt) {
159166
this.arguments = TargetMethod.validateArguments(parameters, collectArguments(), false);
167+
this.resetRequested = false;
168+
close();
169+
}
170+
171+
private void reset(ActionEvent evt) {
172+
this.arguments = new LinkedHashMap<>();
173+
this.resetRequested = true;
160174
close();
161175
}
162176

@@ -175,7 +189,8 @@ void populateOptions() {
175189
Msg.warn(this, "No editor for " + type + "? Trying String instead");
176190
editor = PropertyEditorManager.findEditor(String.class);
177191
}
178-
editor.setValue(computeMemorizedValue(param));
192+
Object val = computeMemorizedValue(param);
193+
editor.setValue(val);
179194
editor.addPropertyChangeListener(this);
180195
pairPanel.add(MiscellaneousUtils.getEditorComponent(editor));
181196
// TODO: How to handle parameter with choices?
@@ -184,10 +199,14 @@ void populateOptions() {
184199
}
185200

186201
protected Map<String, ?> collectArguments() {
187-
return paramEditors.keySet()
188-
.stream()
189-
.collect(Collectors.toMap(param -> param.name,
190-
param -> memorized.get(NameTypePair.fromParameter(param))));
202+
Map<String, Object> map = new LinkedHashMap<>();
203+
for (ParameterDescription<?> param : paramEditors.keySet()) {
204+
Object val = memorized.get(NameTypePair.fromParameter(param));
205+
if (val != null) {
206+
map.put(param.name, val);
207+
}
208+
}
209+
return map;
191210
}
192211

193212
public Map<String, ?> getArguments() {
@@ -196,6 +215,9 @@ void populateOptions() {
196215

197216
public <T> void setMemorizedArgument(String name, Class<T> type, T value) {
198217
//name = addContext(name, currentContext);
218+
if (value == null) {
219+
return;
220+
}
199221
memorized.put(new NameTypePair(name, type), value);
200222
}
201223

@@ -239,4 +261,8 @@ public void readConfigState(SaveState saveState) {
239261
}
240262
}
241263

264+
public boolean isResetRequested() {
265+
return resetRequested;
266+
}
267+
242268
}

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServicePlugin.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,15 @@
6161
import ghidra.util.datastruct.CollectionChangeListener;
6262
import ghidra.util.datastruct.ListenerSet;
6363

64-
@PluginInfo(shortDescription = "Debugger models manager service", description = "Manage debug sessions, connections, and trace recording", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.HIDDEN, servicesRequired = {}, servicesProvided = {
65-
DebuggerModelService.class, })
64+
@PluginInfo(
65+
shortDescription = "Debugger models manager service",
66+
description = "Manage debug sessions, connections, and trace recording",
67+
category = PluginCategoryNames.DEBUGGER,
68+
packageName = DebuggerPluginPackage.NAME,
69+
status = PluginStatus.HIDDEN,
70+
servicesRequired = {},
71+
servicesProvided = {
72+
DebuggerModelService.class, })
6673
public class DebuggerModelServicePlugin extends Plugin
6774
implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin {
6875

@@ -239,7 +246,10 @@ public boolean addModel(DebuggerObjectModel model) {
239246
}
240247
model.addModelListener(forRemovalAndFocusListener);
241248
TargetObject root = model.getModelRoot();
242-
if (!root.isValid()) {
249+
// root == null, probably means we're between model construction
250+
// and root construction, but the model was not closed, so no need
251+
// to invalidate
252+
if (root != null && !root.isValid()) {
243253
forRemovalAndFocusListener.invalidated(root, root,
244254
"Invalidated before or during add to service");
245255
}

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceProxyPlugin.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import ghidra.app.plugin.core.debug.gui.DebuggerResources.DisconnectAllAction;
4040
import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper;
4141
import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer;
42+
import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.PromptMode;
4243
import ghidra.app.plugin.core.debug.utils.BackgroundUtils;
4344
import ghidra.app.services.*;
4445
import ghidra.async.AsyncUtils;
@@ -88,7 +89,7 @@ public class DebuggerModelServiceProxyPlugin extends Plugin
8889
new DebuggerProgramLaunchOffer() {
8990
@Override
9091
public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor,
91-
boolean prompt, LaunchConfigurator configurator) {
92+
PromptMode prompt, LaunchConfigurator configurator) {
9293
throw new AssertionError("Who clicked me?");
9394
}
9495

@@ -330,7 +331,8 @@ protected Stream<DebuggerProgramLaunchOffer> orderOffers(
330331
return offers.sorted(Comparator.comparingInt(o -> -mrl.indexOf(o.getConfigName())));
331332
}
332333

333-
private void debugProgram(DebuggerProgramLaunchOffer offer, Program program, boolean prompt) {
334+
private void debugProgram(DebuggerProgramLaunchOffer offer, Program program,
335+
PromptMode prompt) {
334336
BackgroundUtils.asyncModal(tool, offer.getButtonTitle(), true, true, m -> {
335337
List<String> recent = new ArrayList<>(readMostRecentLaunches(program));
336338
recent.remove(offer.getConfigName());
@@ -360,7 +362,7 @@ private void debugProgramButtonActivated(ActionContext ctx) {
360362
if (offer == null || program == null) {
361363
return;
362364
}
363-
debugProgram(offer, program, false);
365+
debugProgram(offer, program, PromptMode.ON_ERROR);
364366
}
365367

366368
private void debugProgramStateActivated(ActionState<DebuggerProgramLaunchOffer> offer,
@@ -375,7 +377,7 @@ private void debugProgramMenuActivated(DebuggerProgramLaunchOffer offer) {
375377
if (program == null) {
376378
return;
377379
}
378-
debugProgram(offer, program, true);
380+
debugProgram(offer, program, PromptMode.ALWAYS);
379381
}
380382

381383
private void updateActionDebugProgram() {

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package ghidra.app.plugin.core.debug.service.model.launch;
1717

18+
import static ghidra.async.AsyncUtils.*;
19+
1820
import java.io.IOException;
1921
import java.util.*;
22+
import java.util.Map.Entry;
2023
import java.util.concurrent.CancellationException;
2124
import java.util.concurrent.CompletableFuture;
2225
import java.util.stream.Collectors;
@@ -267,7 +270,12 @@ private void saveLauncherArgs(Map<String, ?> args,
267270
if (program == null) {
268271
return Map.of();
269272
}
270-
return Map.of(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, program.getExecutablePath());
273+
Map<String, Object> map = new LinkedHashMap<String, Object>();
274+
for (Entry<String, ParameterDescription<?>> entry : params.entrySet()) {
275+
map.put(entry.getKey(), entry.getValue().defaultValue);
276+
}
277+
map.put(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, program.getExecutablePath());
278+
return map;
271279
}
272280

273281
/**
@@ -282,20 +290,30 @@ private void saveLauncherArgs(Map<String, ?> args,
282290
DebuggerMethodInvocationDialog dialog =
283291
new DebuggerMethodInvocationDialog(tool, getButtonTitle(), "Launch", getIcon());
284292
// NB. Do not invoke read/writeConfigState
285-
Map<String, ?> args = configurator.configureLauncher(launcher,
286-
loadLastLauncherArgs(launcher, true), RelPrompt.BEFORE);
287-
for (ParameterDescription<?> param : params.values()) {
288-
Object val = args.get(param.name);
289-
if (val != null) {
290-
dialog.setMemorizedArgument(param.name, param.type.asSubclass(Object.class), val);
293+
Map<String, ?> args;
294+
boolean reset = false;
295+
do {
296+
args = configurator.configureLauncher(launcher,
297+
loadLastLauncherArgs(launcher, true), RelPrompt.BEFORE);
298+
for (ParameterDescription<?> param : params.values()) {
299+
Object val = args.get(param.name);
300+
if (val != null) {
301+
dialog.setMemorizedArgument(param.name, param.type.asSubclass(Object.class),
302+
val);
303+
}
291304
}
305+
args = dialog.promptArguments(params);
306+
if (args == null) {
307+
// Cancelled
308+
return null;
309+
}
310+
reset = dialog.isResetRequested();
311+
if (reset) {
312+
args = generateDefaultLauncherArgs(params);
313+
}
314+
saveLauncherArgs(args, params);
292315
}
293-
args = dialog.promptArguments(params);
294-
if (args == null) {
295-
// Cancelled
296-
return null;
297-
}
298-
saveLauncherArgs(args, params);
316+
while (reset);
299317
return args;
300318
}
301319

@@ -328,12 +346,15 @@ private void saveLauncherArgs(Map<String, ?> args,
328346
try {
329347
Element element = XmlUtilities.fromString(property);
330348
SaveState state = new SaveState(element);
349+
List<String> names = List.of(state.getNames());
331350
Map<String, Object> args = new LinkedHashMap<>();
332351
for (ParameterDescription<?> param : params.values()) {
333-
Object configState =
334-
ConfigStateField.getState(state, param.type, param.name);
335-
if (configState != null) {
336-
args.put(param.name, configState);
352+
if (names.contains(param.name)) {
353+
Object configState =
354+
ConfigStateField.getState(state, param.type, param.name);
355+
if (configState != null) {
356+
args.put(param.name, configState);
357+
}
337358
}
338359
}
339360
if (!args.isEmpty()) {
@@ -347,7 +368,7 @@ private void saveLauncherArgs(Map<String, ?> args,
347368
e);
348369
}
349370
Msg.error(this,
350-
"Saved launcher args are corrup, or launcher parameters changed. Defaulting.",
371+
"Saved launcher args are corrupt, or launcher parameters changed. Defaulting.",
351372
e);
352373
}
353374
}
@@ -463,12 +484,14 @@ protected CompletableFuture<TargetLauncher> findLauncher(DebuggerObjectModel m)
463484

464485
// Eww.
465486
protected CompletableFuture<Void> launch(TargetLauncher launcher,
466-
boolean prompt, LaunchConfigurator configurator) {
487+
boolean prompt, LaunchConfigurator configurator, TaskMonitor monitor) {
467488
Map<String, ?> args = getLauncherArgs(launcher, prompt, configurator);
468489
if (args == null) {
469490
throw new CancellationException();
470491
}
471-
return launcher.launch(args);
492+
return AsyncTimer.DEFAULT_TIMER.mark()
493+
.timeOut(
494+
launcher.launch(args), getTimeoutMillis(), () -> onTimedOutLaunch(monitor));
472495
}
473496

474497
protected void checkCancelled(TaskMonitor monitor) {
@@ -560,7 +583,7 @@ protected Void onTimedOutMapping(TaskMonitor monitor,
560583
}
561584

562585
@Override
563-
public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolean prompt,
586+
public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, PromptMode mode,
564587
LaunchConfigurator configurator) {
565588
DebuggerModelService service = tool.getService(DebuggerModelService.class);
566589
DebuggerStaticMappingService mappingService =
@@ -573,12 +596,13 @@ public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolea
573596
TargetObject target;
574597
TraceRecorder recorder;
575598
Throwable exception;
599+
boolean prompt = mode == PromptMode.ALWAYS;
576600

577601
LaunchResult getResult() {
578602
return new LaunchResult(model, target, recorder, exception);
579603
}
580604
};
581-
return connect(service, prompt, configurator).thenCompose(m -> {
605+
return connect(service, locals.prompt, configurator).thenCompose(m -> {
582606
checkCancelled(monitor);
583607
locals.model = m;
584608
monitor.incrementProgress(1);
@@ -591,12 +615,14 @@ LaunchResult getResult() {
591615
monitor.incrementProgress(1);
592616
monitor.setMessage("Launching");
593617
locals.futureTarget = listenForTarget(l.getModel());
594-
if (prompt) {
595-
return launch(l, true, configurator);
596-
}
597-
return AsyncTimer.DEFAULT_TIMER.mark()
598-
.timeOut(launch(l, false, configurator), getTimeoutMillis(),
599-
() -> onTimedOutLaunch(monitor));
618+
return loop(TypeSpec.VOID, (loop) -> {
619+
launch(l, locals.prompt, configurator, monitor).thenAccept(loop::exit)
620+
.exceptionally(ex -> {
621+
loop.repeat();
622+
return null;
623+
});
624+
locals.prompt = mode != PromptMode.NEVER;
625+
});
600626
}).thenCompose(__ -> {
601627
checkCancelled(monitor);
602628
monitor.incrementProgress(1);
@@ -636,4 +662,5 @@ LaunchResult getResult() {
636662
return locals.getResult();
637663
});
638664
}
665+
639666
}

‎Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOffer.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ public enum RelPrompt {
8282
AFTER;
8383
}
8484

85+
public enum PromptMode {
86+
/**
87+
* The user is always prompted for parameters.
88+
*/
89+
ALWAYS,
90+
/**
91+
* The user is never prompted for parameters.
92+
*/
93+
NEVER,
94+
/**
95+
* The user is prompted after an error.
96+
*/
97+
ON_ERROR;
98+
}
99+
85100
/**
86101
* Callbacks for custom configuration when launching a program
87102
*/
@@ -118,7 +133,7 @@ default void configureConnector(DebuggerModelFactory factory) {
118133
* @param configurator the configuration callbacks
119134
* @return a future which completes when the program is launched
120135
*/
121-
CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolean prompt,
136+
CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, PromptMode prompt,
122137
LaunchConfigurator configurator);
123138

124139
/**
@@ -128,7 +143,7 @@ CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolean promp
128143
* @param prompt if the user should be prompted to confirm launch parameters
129144
* @return a future which completes when the program is launched
130145
*/
131-
default CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolean prompt) {
146+
default CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, PromptMode prompt) {
132147
return launchProgram(monitor, prompt, LaunchConfigurator.NOP);
133148
}
134149

‎Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ default DebuggerProgramLaunchOffer requireLaunchOffer(Program program) {
14911491
default LaunchResult launch(DebuggerProgramLaunchOffer offer, String commandLine,
14921492
TaskMonitor monitor) {
14931493
try {
1494-
return waitOn(offer.launchProgram(monitor, false, new LaunchConfigurator() {
1494+
return waitOn(offer.launchProgram(monitor, PromptMode.NEVER, new LaunchConfigurator() {
14951495
@Override
14961496
public Map<String, ?> configureLauncher(TargetLauncher launcher,
14971497
Map<String, ?> arguments, RelPrompt relPrompt) {
@@ -1514,7 +1514,7 @@ default LaunchResult launch(DebuggerProgramLaunchOffer offer, String commandLine
15141514
*/
15151515
default LaunchResult launch(DebuggerProgramLaunchOffer offer, TaskMonitor monitor) {
15161516
try {
1517-
return waitOn(offer.launchProgram(monitor, false));
1517+
return waitOn(offer.launchProgram(monitor, PromptMode.NEVER));
15181518
}
15191519
catch (InterruptedException | ExecutionException | TimeoutException e) {
15201520
// TODO: This is not ideal, since it's likely partially completed

‎Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package ghidra.app.plugin.core.debug.service.model;
1717

18-
import static org.junit.Assert.assertEquals;
18+
import static org.junit.Assert.*;
1919

2020
import java.util.Collection;
2121
import java.util.List;
@@ -35,7 +35,7 @@ public class TestDebuggerProgramLaunchOpinion implements DebuggerProgramLaunchOp
3535

3636
public static class TestDebuggerProgramLaunchOffer implements DebuggerProgramLaunchOffer {
3737
@Override
38-
public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, boolean prompt,
38+
public CompletableFuture<LaunchResult> launchProgram(TaskMonitor monitor, PromptMode prompt,
3939
LaunchConfigurator configurator) {
4040
return CompletableFuture
4141
.completedFuture(LaunchResult.totalFailure(new AssertionError()));

‎Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetLauncher.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,5 @@ default public TargetParameterMap getParameters() {
139139
* @return a future which completes when the command is completed
140140
*/
141141
public CompletableFuture<Void> launch(Map<String, ?> args);
142+
142143
}

0 commit comments

Comments
 (0)
Please sign in to comment.