From bb0ba6fd91e6ffd9bc657096d85a0ce73c401085 Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Fri, 11 Mar 2016 11:06:43 -0500 Subject: [PATCH] Bug 489455 - Add new breakpoint action to run arbitrary debugger command This is generic support for debugger commands though mi console bridge, should be not gdb specific (have a simple gdb implementation though) We add new breakpoint action called "Debugger Command" Interface allows to enter arbitrary string(s) This is interpreted by debugger as it see fit For gdb implementation these are cli commands Change-Id: I20ca0b8b094c724e1cf8b0691f4f6cab84a3737d --- .../ICLIDebugActionEnabler.java | 26 ++++ .../plugin.properties | 1 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 17 +++ .../ui/breakpointactions/ActionDialog.java | 19 +-- .../breakpointactions/CLICommandAction.java | 124 ++++++++++++++++++ .../CLICommandActionComposite.java | 43 ++++++ .../CLICommandActionPage.java | 45 +++++++ .../ui/breakpointactions/messages.properties | 7 + .../actions/BreakpointActionAdapter.java | 4 + .../actions/CLIDebugActionEnabler.java | 87 ++++++++++++ 10 files changed, 364 insertions(+), 9 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java new file mode 100644 index 00000000000..ed6970fbd02 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) Mar 11, 2016 QNX Software Systems. All Rights Reserved. + * + * You must obtain a written license from and pay applicable license fees to QNX + * Software Systems before you may reproduce, modify or distribute this software, + * or any work that includes all or part of this software. Free development + * licenses are available for evaluation and non-commercial purposes. For more + * information visit [http://licensing.qnx.com] or email licensing@qnx.com. + * + * This file may contain contributions from others. Please review this entire + * file for other proprietary rights or license notices, as well as the QNX + * Development Suite License Guide at [http://licensing.qnx.com/license-guide/] + * for other information. + *******************************************************************************/ +package org.eclipse.cdt.debug.core.breakpointactions; + +/** + * This interface intended to pass arbitrary debugger command to backend, + * usually intended for command line debugger or scripting. Debugger can interpret this as it see fit + * (including splitting this into multiple commands) + * + * @since 8.0 + */ +public interface ICLIDebugActionEnabler { + void execute(String command) throws Exception; +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index 9c798eda526..01b1e40e46b 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -173,6 +173,7 @@ LogAction.name=Log Action ResumeAction.name=Resume Action ExternalToolAction.name=External Tool Action ReverseDebugAction.name=Reverse Debug Action +CLICommandAction.name=Debugger Command Action # Breakpoint Types breapointType.label=Type diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index d31bd8b93ae..ee795660e37 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1300,6 +1300,23 @@ id="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugActionPage"> + + + + + + + + + 32) + summary = summary.substring(0, 32); + return summary; + } + + @Override + public String getTypeName() { + return Messages.getString("CLICommandAction.TypeName"); //$NON-NLS-1$ + } + + @Override + public void initializeFromMemento(String data) { + try { + Element root = DebugPlugin.parseDocument(data); + String value = root.getAttribute(COMMAND_ATT); + if (value == null) + value = ""; //$NON-NLS-1$ + command = value; + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java new file mode 100644 index 00000000000..2ee432bc6ba --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpointactions; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * This composite show a little text field (multi-line) that allow to enter to enter debugger commands. + * Interpretation of that depends on the backend + * + * @since 8.0 + */ +public class CLICommandActionComposite extends Composite { + private Text command; + + public CLICommandActionComposite(Composite parent, int style, CLICommandActionPage commandActionPage) { + super(parent, style); + setLayout(GridLayoutFactory.fillDefaults().create()); + Label messageToLogLabel = new Label(this, SWT.NONE); + messageToLogLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + messageToLogLabel.setText(Messages.getString("CLICommandActionComposite.0")); //$NON-NLS-1$ + command = new Text(this, SWT.BORDER | SWT.WRAP); + command.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); + command.setText(commandActionPage.getCLICommandAction().getCommand()); + } + + public String getCommand() { + return command.getText(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java new file mode 100644 index 00000000000..7b6d606a89a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpointactions; + +import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction; +import org.eclipse.cdt.debug.ui.breakpointactions.IBreakpointActionPage; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.swt.widgets.Composite; + +/** + * @since 8.0 + */ +public class CLICommandActionPage extends PlatformObject implements + IBreakpointActionPage { + private CLICommandAction cliCommandAction; + private CLICommandActionComposite editor; + + public CLICommandAction getCLICommandAction() { + return cliCommandAction; + } + + @Override + public void actionDialogCanceled() { + } + + @Override + public void actionDialogOK() { + cliCommandAction.setCommand(editor.getCommand()); + } + + @Override + public Composite createComposite(IBreakpointAction action, Composite composite, int style) { + cliCommandAction = (CLICommandAction) action; + editor = new CLICommandActionComposite(composite, style, this); + return editor; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties index 7457b01b466..0f364b6fbc3 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties @@ -71,3 +71,10 @@ ReverseDebugAction.error.1=Could not do reverse debug operation ReverseDebugAction.enable=Enable ReverseDebugAction.disable=Disable ReverseDebugAction.toggle=Toggle + +CLICommandActionComposite.0=Debugger command(s) to run when the breakpoint is hit: +CLICommandAction.ConsoleTitle=Debugger Command Action Messages +CLICommandAction.UntitledName=Untitled Debugger Command Action +CLICommandAction.TypeName=Debugger Command Action +CLICommandAction.error.0=Could not execute debugger command action: "{0}". +CLICommandAction.NoSupport=Your debugger integration does not support direct exectution of commands diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java index ff9ef38922a..4ac2c735de9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; +import org.eclipse.cdt.debug.core.breakpointactions.ICLIDebugActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler; @@ -47,6 +48,9 @@ public class BreakpointActionAdapter implements IAdaptable { if (adapter.equals(IReverseDebugEnabler.class)) { return (T)new MIReverseDebugEnabler(fExecutor, fServiceTracker, fContext); } + if (adapter.equals(ICLIDebugActionEnabler.class)) { + return (T)new CLIDebugActionEnabler(fExecutor, fServiceTracker, fContext); + } return null; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java new file mode 100644 index 00000000000..9b9d651af9e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; + +import org.eclipse.cdt.debug.core.breakpointactions.ICLIDebugActionEnabler; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.command.ICommand; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor; +import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; + +/** + * + * This class permits to execute custom user debugger commands through cli/mi bridge + * + * @since 5.0 + */ +public class CLIDebugActionEnabler implements ICLIDebugActionEnabler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final ICommandControlDMContext fContext; + private ICommandControlService fCommandControl; + + /** + * @param executor + * @param serviceTracker + * @param context + */ + public CLIDebugActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + fContext = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class); + fCommandControl = fServiceTracker.getService(ICommandControlService.class); + assert fContext != null; + } + + @Override + public void execute(String commandmulti) throws Exception { + String[] commands = commandmulti.split("\\r?\\n"); //$NON-NLS-1$ + for (int j = 0; j < commands.length; ++j) { + String single = commands[j]; + executeSingleCommand(single); + } + } + + private boolean isMIOperation(String operation) { + if (operation.startsWith("-")) { //$NON-NLS-1$ + return true; + } + return false; + } + + private void executeSingleCommand(String str) { + // Do not use the interpreter-exec for stepping operation the UI will fall out of step. + // Also, do not use "interpreter-exec console" for MI commands. + ICommand cmd; + if (!isMIOperation(str) && + !CLIEventProcessor.isSteppingOperation(str)) { + cmd = new MIInterpreterExecConsole<>(fContext, str); + } else { + cmd = new CLICommand<>(fContext, str); + } + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + // TODO: for print command would be nice to redirect to gdb console + fCommandControl.queueCommand(cmd, new ImmediateDataRequestMonitor<>()); + } + }); + } +}