1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 338136: Show the proper inferior console when selecting a container in the debug view. This support is for multi-process.

This commit is contained in:
Marc Khouzam 2011-03-07 11:35:07 +00:00
parent 28f527f165
commit 745fbced67
6 changed files with 192 additions and 34 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Marc-Andre Laperle and others.
* Copyright (c) 2010, 2011 Marc-Andre Laperle 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
@ -10,25 +10,52 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.console;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsolePageParticipant;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.part.IPageBookViewPage;
/**
* A console page participant for both the gdb tracing console and the gdb CLI console
* A console page participant for DSF-GDB.
* It adds a save button to both the gdb tracing console and the gdb CLI console.
* It also brings to the front the proper inferior console when a container is selected.
*
* @since 2.1
*/
public class ConsolePageParticipant implements IConsolePageParticipant{
public class ConsolePageParticipant implements IConsolePageParticipant, IDebugContextListener {
private IConsole fConsole;
private IPageBookViewPage fPage;
private IConsoleView fView;
public void init(IPageBookViewPage page, IConsole console) {
if(console instanceof TracingConsole || isConsoleGdbCli(console))
{
fPage = page;
fConsole = console;
fView = (IConsoleView)fPage.getSite().getPage().findView(IConsoleConstants.ID_CONSOLE_VIEW);
if (isConsoleInferior(console) || isConsoleGdbCli(console)) {
// This console participant will affect all consoles, even those not for DSF-GDB.
// Only consoles for GDBProcess or InferiorRuntimeProcess are what we care about for DSF-GDB
DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).addDebugContextListener(this);
}
if(console instanceof TracingConsole || isConsoleGdbCli(console)) {
TextConsole textConsole = (TextConsole) console;
// Add the save console action
@ -55,12 +82,30 @@ public class ConsolePageParticipant implements IConsolePageParticipant{
return false;
}
/**
* Checks if the the console is for an inferior.
*
* @param console The console to check
* @return true if the the console is for an inferior
*/
private boolean isConsoleInferior(IConsole console) {
if(console instanceof org.eclipse.debug.ui.console.IConsole) {
org.eclipse.debug.ui.console.IConsole debugConsole = (org.eclipse.debug.ui.console.IConsole)console;
return (debugConsole.getProcess() instanceof InferiorRuntimeProcess);
}
return false;
}
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
return null;
}
public void dispose() {
if (isConsoleInferior(fConsole) || isConsoleGdbCli(fConsole)) {
DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).removeDebugContextListener(this);
}
fConsole = null;
}
public void activated() {
@ -69,4 +114,68 @@ public class ConsolePageParticipant implements IConsolePageParticipant{
public void deactivated() {
}
protected IProcess getConsoleProcess() {
if (fConsole instanceof org.eclipse.debug.ui.console.IConsole) {
return ((org.eclipse.debug.ui.console.IConsole)fConsole).getProcess();
}
return null;
}
protected IProcess getCurrentProcess() {
IAdaptable context = DebugUITools.getDebugContext();
// If the launch is selected, we should choose the first inferior being debugged
if (context instanceof ILaunch) {
ILaunch launch = (ILaunch)context;
IProcess[] processes = launch.getProcesses();
if (processes != null && processes.length > 0) {
for (IProcess process : processes) {
if (process instanceof InferiorRuntimeProcess) {
return process;
}
}
// No inferior? return the gdb process
// We have to check that the process is actually from a DSF-GDB session,
// since the current context could be for any debug session
if (processes[0] instanceof GDBProcess) {
return launch.getProcesses()[0];
}
}
return null;
}
if (context != null) {
// Look for the process that this context refers to, so we can select its console
IDMContext dmc = (IDMContext)context.getAdapter(IDMContext.class);
IMIContainerDMContext container = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
if (container != null) {
ILaunch launch = (ILaunch)context.getAdapter(ILaunch.class);
if (launch != null) {
for (IProcess process : launch.getProcesses()) {
String groupId = process.getAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR);
if (container.getGroupId().equals(groupId)) {
return process;
}
}
}
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener#contextEvent(org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent)
*/
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
IProcess consoleProcess = getConsoleProcess();
if (fView != null && consoleProcess != null && consoleProcess.equals(getCurrentProcess())) {
fView.display(fConsole);
}
}
}
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2011 Ericsson 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:
* Ericsson - initial implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
/**
* @noimplement This interface is not intended to be implemented by clients.
* @since 4.0
*/
public interface IGdbDebugConstants {
public static final String PREFIX = GdbPlugin.PLUGIN_ID + "."; //$NON-NLS-1$
/**
* Attribute key to be added to the IProcess associated with an IMIContainerDMContext.
* The value should be the groupId as returned by {@link IMIContainerDMContext#getGroupId()}
*/
public static final String INFERIOR_GROUPID_ATTR = PREFIX + "inferiorGroupId"; //$NON-NLS-1$
}

View file

@ -52,7 +52,6 @@ import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IDisconnect;
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.ITerminate;
@ -171,18 +170,6 @@ public class GdbLaunch extends DsfLaunch
GDBProcess gdbProcess = new GDBProcess(this, cliProc, label, null);
addProcess(gdbProcess);
Object existingAdapter = getSession().getModelAdapter(IProcess.class);
if (existingAdapter == null) {
// Register the model adapter to the gdbProcess only if there is no other one
// registered already; if there is already one, it is from our inferior process
// and it takes precedence because we want the inferior console to show
// when we select a debug context of this debug session.
// If the inferior process is added later, it will properly overwrite this model adapter.
// Note that we don't always have an inferior console, so it is important to register
// this adapter for those cases.
getSession().registerModelAdapter(IProcess.class, gdbProcess);
}
} catch (InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
} catch (ExecutionException e) {

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2011 Ericsson 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:
* Ericsson - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.launching;
import java.util.Map;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.RuntimeProcess;
/**
* A process for the inferior to know it belongs to a DSF-GDB session
*
* @since 4.0
*/
public class InferiorRuntimeProcess extends RuntimeProcess {
public InferiorRuntimeProcess(ILaunch launch, Process process, String name,
Map<String, String> attributes) {
super(launch, process, name, attributes);
}
}

View file

@ -34,9 +34,10 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
@ -463,7 +464,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
IProcess[] launchProcesses = launch.getProcesses();
for (IProcess p : launchProcesses) {
// We know there is only one inferior, so just find it.
if ((p instanceof GDBProcess) == false) {
if (p instanceof InferiorRuntimeProcess) {
launch.removeProcess(p);
break;
}
@ -471,11 +472,10 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
}
// Add the inferior
IProcess process = DebugPlugin.newProcess(launch, inferior, label);
InferiorRuntimeProcess runtimeInferior = new InferiorRuntimeProcess(launch, inferior, label, null);
runtimeInferior.setAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR, MIProcesses.UNIQUE_GROUP_ID);
launch.addProcess(runtimeInferior);
// Register as an IProcess so that the console is brought to the front
// when the inferior is selected
getSession().registerModelAdapter(IProcess.class, process);
rm.done();
}
});

View file

@ -26,7 +26,9 @@ import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContex
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
@ -53,9 +55,7 @@ import org.eclipse.debug.core.model.IProcess;
* @since 4.0
*/
public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence {
private static final String GROUP_ATTR = GdbPlugin.PLUGIN_ID + "groupId"; //$NON-NLS-1$
private IGDBControl fCommandControl;
private CommandFactory fCommandFactory;
private IGDBProcesses fProcService;
@ -290,7 +290,7 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence {
// For a restart, remove the old inferior
IProcess[] launchProcesses = launch.getProcesses();
for (IProcess process : launchProcesses) {
String groupAttribute = process.getAttribute(GROUP_ATTR);
String groupAttribute = process.getAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR);
if (groupId.equals(groupAttribute)) {
launch.removeProcess(process);
// Use the exact same label as before
@ -301,12 +301,10 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence {
}
// Add the inferior
IProcess process = DebugPlugin.newProcess(launch, inferior, label);
process.setAttribute(GROUP_ATTR, groupId);
// Register as an IProcess so that the console is brought to the front
// when the inferior is selected
session.registerModelAdapter(IProcess.class, process);
InferiorRuntimeProcess runtimeInferior = new InferiorRuntimeProcess(launch, inferior, label, null);
runtimeInferior.setAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR, groupId);
launch.addProcess(runtimeInferior);
rm.done();
}
});