diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java index 6070c328881..26862376a32 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java @@ -20,16 +20,17 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.AbstractContainerVMNode; +import org.eclipse.dd.dsf.debug.service.IProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBProcessData; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; -import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; @@ -55,53 +56,72 @@ public class ContainerVMNode extends AbstractContainerVMNode } @Override - protected void updateElementsInSessionThread(IChildrenUpdate update) { - GDBControl controlService = getServicesTracker().getService(GDBControl.class); - if ( controlService == null ) { - handleFailedUpdate(update); - return; - } - - MIInferiorProcess inferiorProcess = controlService.getInferiorProcess(); - if (inferiorProcess != null && inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) { - update.setChild(createVMContext(inferiorProcess.getExecutionContext()), 0); - } - update.done(); + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + IProcesses processService = getServicesTracker().getService(IProcesses.class); + GDBControl controlService = getServicesTracker().getService(GDBControl.class); + if (processService == null || controlService == null) { + handleFailedUpdate(update); + return; + } + + processService.getProcessesBeingDebugged( + controlService.getGDBDMContext(), + new ViewerDataRequestMonitor(getExecutor(), update) { + @Override + public void handleCompleted() { + if (!isSuccess()) { + handleFailedUpdate(update); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); } - @Override + @Override protected void updateLabelInSessionThread(final ILabelUpdate update) { - final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); - if ( runControl == null ) { - handleFailedUpdate(update); - return; - } - - final GDBControlDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), GDBControlDMContext.class); + IProcesses processService = getServicesTracker().getService(IProcesses.class); + IRunControl runControl = getServicesTracker().getService(IRunControl.class); + if (processService == null) { + handleFailedUpdate(update); + return; + } - String imageKey = null; - if (runControl.isSuspended(dmc)) { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; - } else { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; - } - update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - - runControl.getProcessData( - dmc, - new ViewerDataRequestMonitor(getExecutor(), update) { - @Override - public void handleCompleted() { - if (!isSuccess()) { - update.done(); - return; - } - update.setLabel(getData().getName(), 0); - update.done(); - } - }); - } + final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class); + final IContainerDMContext contDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IContainerDMContext.class); + + String imageKey = null; + if (runControl.isSuspended(contDmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + processService.getExecutionData( + procDmc, + new ViewerDataRequestMonitor(getExecutor(), update) { + @Override + public void handleCompleted() { + if (!isSuccess()) { + update.setLabel("", 0); //$NON-NLS-1$ + update.done(); + return; + } + + // Create Labels of type Name[PID] if the pid is available + final StringBuilder builder = new StringBuilder(); + builder.append(getData().getName()); + if (getData().getId() != null && getData().getId().length() > 0) { + builder.append("[" + getData().getId()+ "]"); //$NON-NLS-1$//$NON-NLS-2$ + } + update.setLabel(builder.toString(), 0); + update.done(); + } + }); + } @Override public int getDeltaFlags(Object e) { @@ -133,53 +153,55 @@ public class ContainerVMNode extends AbstractContainerVMNode private final String MEMENTO_NAME = "CONTAINER_MEMENTO_NAME"; //$NON-NLS-1$ public void compareElements(IElementCompareRequest[] requests) { - - for ( final IElementCompareRequest request : requests ) { - - Object element = request.getElement(); - final IMemento memento = request.getMemento(); - final String mementoName = memento.getString(MEMENTO_NAME); - - if (mementoName != null) { - if (element instanceof IDMVMContext) { - - IDMContext dmc = ((IDMVMContext)element).getDMContext(); - - if ( dmc instanceof GDBControlDMContext ) - { - final GDBControlDMContext procDmc = (GDBControlDMContext) dmc; - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); - if ( runControl != null ) { - runControl.getProcessData( - procDmc, - new ViewerDataRequestMonitor(runControl.getExecutor(), request) { - @Override - protected void handleCompleted() { - if ( getStatus().isOK() ) { - request.setEqual( mementoName.equals( "Container." + getData().getName() ) ); //$NON-NLS-1$ - } - request.done(); - } - }); - } - else { - request.done(); - } - } - }); - } catch (RejectedExecutionException e) { - request.done(); - } + for (final IElementCompareRequest request : requests) { - continue; - } - } - } - request.done(); - } + Object element = request.getElement(); + final IMemento memento = request.getMemento(); + final String mementoName = memento.getString(MEMENTO_NAME); + + if (mementoName != null) { + if (element instanceof IDMVMContext) { + + IDMContext dmc = ((IDMVMContext)element).getDMContext(); + + if (dmc instanceof IContainerDMContext) + { + final IProcessDMContext procDmc = findDmcInPath(request.getViewerInput(), request.getElementPath(), IProcessDMContext.class); + + if (procDmc != null) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + final IProcesses processService = getServicesTracker().getService(IProcesses.class); + if (processService != null) { + processService.getExecutionData( + procDmc, + new ViewerDataRequestMonitor(processService.getExecutor(), request) { + @Override + protected void handleCompleted() { + if ( getStatus().isOK() ) { + memento.putString(MEMENTO_NAME, "Container." + getData().getName() + getData().getId()); //$NON-NLS-1$ + } + request.done(); + } + }); + } + else { + request.done(); + } + } + }); + } catch (RejectedExecutionException e) { + request.done(); + } + + continue; + } + } + } + } + request.done(); + } } /* @@ -187,49 +209,50 @@ public class ContainerVMNode extends AbstractContainerVMNode * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#encodeElements(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest[]) */ public void encodeElements(IElementMementoRequest[] requests) { - - for ( final IElementMementoRequest request : requests ) { - - Object element = request.getElement(); - final IMemento memento = request.getMemento(); - - if (element instanceof IDMVMContext) { - - IDMContext dmc = ((IDMVMContext)element).getDMContext(); - - if ( dmc instanceof GDBControlDMContext ) - { - final GDBControlDMContext procDmc = (GDBControlDMContext) dmc; - try { - getSession().getExecutor().execute(new DsfRunnable() { - public void run() { - final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); - if ( runControl != null ) { - runControl.getProcessData( - procDmc, - new ViewerDataRequestMonitor(runControl.getExecutor(), request) { - @Override - protected void handleCompleted() { - if ( getStatus().isOK() ) { - memento.putString(MEMENTO_NAME, "Container." + getData().getName()); //$NON-NLS-1$ - } - request.done(); - } - }); - } - else { - request.done(); - } - } - }); - } catch (RejectedExecutionException e) { - request.done(); - } + for (final IElementMementoRequest request : requests) { - continue; - } - } - request.done(); - } + Object element = request.getElement(); + final IMemento memento = request.getMemento(); + + if (element instanceof IDMVMContext) { + + IDMContext dmc = ((IDMVMContext)element).getDMContext(); + + if (dmc instanceof IContainerDMContext) + { + final IProcessDMContext procDmc = findDmcInPath(request.getViewerInput(), request.getElementPath(), IProcessDMContext.class); + + if (procDmc != null) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + final IProcesses processService = getServicesTracker().getService(IProcesses.class); + if (processService != null) { + processService.getExecutionData( + procDmc, + new ViewerDataRequestMonitor(processService.getExecutor(), request) { + @Override + protected void handleCompleted() { + if ( getStatus().isOK() ) { + memento.putString(MEMENTO_NAME, "Container." + getData().getName() + getData().getId()); //$NON-NLS-1$ + } + request.done(); + } + }); + } else { + request.done(); + } + } + }); + } catch (RejectedExecutionException e) { + request.done(); + } + + continue; + } + } + } + request.done(); + } } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java index 28c97a38d81..7af2ceb7529 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBProcesses.java @@ -21,120 +21,22 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IProcesses; -import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.GdbPlugin; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; -import org.eclipse.dd.mi.service.IMIProcessDMContext; -import org.eclipse.dd.mi.service.command.commands.CLIAttach; +import org.eclipse.dd.mi.service.MIProcesses; import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses; import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo; -import org.eclipse.dd.mi.service.command.output.MIInfo; import org.osgi.framework.BundleContext; -public class GDBProcesses extends AbstractDsfService implements IProcesses { - - @Immutable - protected class GdbThreadDMC extends AbstractDMContext - implements IThreadDMContext - { - /** - * ID given by the OS. - */ - private final String fOSId; - - /** - * Constructor for the context. It should not be called directly by clients. - * Instead clients should call {@link GDBProcesses#createThreadContext} - * to create instances of this context based on the thread ID. - *

- * - * @param sessionId Session that this context belongs to. - * @param processDmc The process that this thread belongs to. - * @param id thread identifier. - */ - protected GdbThreadDMC(String sessionId, IProcessDMContext processDmc, String id) { - super(sessionId, processDmc != null ? new IDMContext[] { processDmc } : new IDMContext[0]); - fOSId = id; - } - - /** - * Returns the thread identifier of this context. - * @return - */ - public String getId(){ return fOSId; } - - @Override - public String toString() { return baseToString() + ".thread[" + fOSId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - - @Override - public boolean equals(Object obj) { - return super.baseEquals(obj) && ((GdbThreadDMC)obj).fOSId == fOSId; - } - - @Override - public int hashCode() { return super.baseHashCode() ^ fOSId.hashCode(); } - } - - @Immutable - protected class GdbProcessDMC extends GdbThreadDMC - implements IMIProcessDMContext - { - /** - * Constructor for the context. It should not be called directly by clients. - * Instead clients should call {@link GDBProcesses#createProcessContext} - * to create instances of this context based on the PID. - *

- * - * @param sessionId Session that this context belongs to. - * @param id process identifier. - */ - protected GdbProcessDMC(String sessionId, String id) { - super(sessionId, null, id); - } - - public String getProcId() { return getId(); } - - @Override - public String toString() { return baseToString() + ".proc[" + getId() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - - @Override - public boolean equals(Object obj) { - return super.equals(obj); - } - - @Override - public int hashCode() { return super.hashCode(); } - } - - /* - * The data of a corresponding thread or process. - */ - @Immutable - private static class GdbThreadDMData implements IThreadDMData { - final String fName; - final String fId; - - GdbThreadDMData(String name, String id) { - fName = name; - fId = id; - } - - public String getId() { return fId; } - public String getName() { return fName; } - public boolean isDebuggerAttached() { - return true; - } - } +public class GDBProcesses extends MIProcesses { - private GDBControl fCommandControl; + private GDBControl fGdb; // A map of pid to names. It is filled when we get all the // processes that are running @@ -144,12 +46,6 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { super(session); } - /** - * This method initializes this service. - * - * @param requestMonitor - * The request monitor indicating the operation is finished - */ @Override public void initialize(final RequestMonitor requestMonitor) { super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @@ -170,23 +66,17 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { */ private void doInitialize(RequestMonitor requestMonitor) { + fGdb = getServicesTracker().getService(GDBControl.class); + // Register this service. register(new String[] { IProcesses.class.getName(), + MIProcesses.class.getName(), GDBProcesses.class.getName() }, new Hashtable()); - - fCommandControl = getServicesTracker().getService(GDBControl.class); requestMonitor.done(); } - /** - * This method shuts down this service. It unregisters the service, stops - * receiving service events, and calls the superclass shutdown() method to - * finish the shutdown process. - * - * @return void - */ @Override public void shutdown(RequestMonitor requestMonitor) { unregister(); @@ -201,51 +91,13 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { return GdbPlugin.getBundleContext(); } - /** - * Create a thread context. - * - * @param process The parent process context - * @param threadId The OS Id of the thread - */ - public IThreadDMContext createThreadContext(IProcessDMContext process, String threadId) { - return new GdbThreadDMC(getSession().getId(), process, threadId); - } - - /** - * Create a process context. - * - * @param pid The OS Id of the process - */ - public IProcessDMContext createProcessContext(String pid) { - return new GdbProcessDMC(getSession().getId(), pid); - } - - /** - * This method obtains the model data for a given GdbThreadDMC object - * which can represent a thread or a process. - * - * @param dmc - * The context for which we are requesting the data - * @param rm - * The request monitor that will contain the requested data - */ - @SuppressWarnings("unchecked") - public void getModelData(IDMContext dmc, DataRequestMonitor rm) { - if (dmc instanceof IThreadDMContext) { - getExecutionData((IThreadDMContext) dmc, - (DataRequestMonitor) rm); - } else { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - + @Override public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor rm) { // We must first check for GdbProcessDMC because it is also a GdbThreadDMC - if (dmc instanceof GdbProcessDMC) { - String pidStr = ((GdbProcessDMC)dmc).getId(); - int pid = 0; + if (dmc instanceof MIProcessDMC) { + String pidStr = ((MIProcessDMC)dmc).getId(); + int pid = -1; try { pid = Integer.parseInt(pidStr); } catch (NumberFormatException e) { @@ -253,85 +105,17 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { String name = fProcessNames.get(pid); // If we don't find the name in our list, return the default name of our program - if (name == null) name = fCommandControl.getExecutablePath().lastSegment(); - rm.setData(new GdbThreadDMData(name, pidStr)); - rm.done(); - } else if (dmc instanceof GdbThreadDMC) { - rm.setData(new GdbThreadDMData("", ((GdbThreadDMC)dmc).getId())); //$NON-NLS-1$ + if (name == null) name = fGdb.getExecutablePath().lastSegment(); + rm.setData(new MIThreadDMData(name, pidStr)); rm.done(); } else { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); + super.getExecutionData(dmc, rm); } } - public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void attachDebuggerToProcess(IProcessDMContext procCtx, final DataRequestMonitor rm) { - if (procCtx instanceof IMIProcessDMContext) { - fCommandControl.queueCommand( - new CLIAttach((IMIProcessDMContext)procCtx), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleSuccess() { - rm.setData(fCommandControl.getGDBDMContext()); - rm.done(); - } - }); - - } else { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void detachDebuggerFromProcess(IProcessDMContext procCtx, final RequestMonitor rm) { -// if (procCtx instanceof GdbProcessDMC) { -// int pid; -// try { -// pid = Integer.parseInt(((GdbProcessDMC)procCtx).getId()); -// } catch (NumberFormatException e) { -// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid process id.", null)); //$NON-NLS-1$ -// rm.done(); -// return; -// } -// -// fCommandControl.queueCommand( -// new CLIDetach(procCtx, pid), -// new DataRequestMonitor(getExecutor(), rm)); -// } else { -// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$ -// rm.done(); -// } - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void canTerminate(IThreadDMContext thread, DataRequestMonitor rm) { - rm.setData(true); - rm.done(); - } - - public void debugNewProcess(String file, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor rm) { - // use -list-thread-groups - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - + @Override public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor rm) { - if (fCommandControl.getSessionType() == SessionType.LOCAL) { + if (fGdb.getSessionType() == SessionType.LOCAL) { IProcessList list = null; try { list = CCorePlugin.getDefault().getProcessList(); @@ -352,7 +136,7 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { rm.done(); } else { // monitor list processes is only for remote session - fCommandControl.queueCommand( + fGdb.queueCommand( new CLIMonitorListProcesses(dmc), new DataRequestMonitor(getExecutor(), rm) { @Override @@ -376,23 +160,17 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses { } private IProcessDMContext[] makeProcessDMCs(IProcessInfo[] processes) { - IProcessDMContext[] procDmcs = new GdbProcessDMC[processes.length]; + IProcessDMContext[] procDmcs = new MIProcessDMC[processes.length]; for (int i=0; i rm) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void terminate(IThreadDMContext thread, RequestMonitor rm) { - if (thread instanceof GdbProcessDMC) { - fCommandControl.terminate(rm); + + @Override + public void terminate(IThreadDMContext thread, RequestMonitor rm) { + if (thread instanceof MIProcessDMC) { + fGdb.terminate(rm); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$ rm.done(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java new file mode 100644 index 00000000000..b0e904535b0 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIProcesses.java @@ -0,0 +1,395 @@ +/******************************************************************************* + * Copyright (c) 2008 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.dd.mi.service; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.command.ICommandControl; +import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.commands.CLIAttach; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.osgi.framework.BundleContext; + + +public class MIProcesses extends AbstractDsfService implements IProcesses { + /* + * Context representing a thread group of GDB/MI. + */ + @Immutable + protected class MIExecutionGroupDMC extends AbstractDMContext + implements IMIExecutionGroupDMContext + { + /** + * String ID that is used to identify the thread group in the GDB/MI protocol. + */ + private final String fId; + + /** + * Constructor for the context. It should not be called directly by clients. + * Instead clients should call {@link MIRunControl#createMIExecutionGroupContext + * to create instances of this context based on the group name. + * + * @param sessionId Session that this context belongs to. + * @param containerDmc The container that this context belongs to. + * @param processDmc The process dmc that also is the parent of this context. + * @param groupId GDB/MI thread group identifier. + */ + protected MIExecutionGroupDMC(String sessionId, IContainerDMContext containerDmc, + IProcessDMContext processDmc, String groupId) { + super(sessionId, containerDmc == null && processDmc == null ? new IDMContext[0] : + containerDmc == null ? new IDMContext[] { processDmc } : + processDmc == null ? new IDMContext[] { containerDmc } : + new IDMContext[] { processDmc, containerDmc }); + fId = groupId; + } + + /** + * Returns the GDB/MI thread group identifier of this context. + */ + public String getGroupId(){ return fId; } + + @Override + public String toString() { return baseToString() + ".threadGroup[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && ((MIExecutionGroupDMC)obj).fId == fId; + } + + @Override + public int hashCode() { return super.baseHashCode() + fId.hashCode(); } + } + + @Immutable + protected class MIThreadDMC extends AbstractDMContext + implements IThreadDMContext + { + /** + * ID given by the OS. + */ + private final String fOSId; + + /** + * Constructor for the context. It should not be called directly by clients. + * Instead clients should call {@link MIProcesses#createThreadContext} + * to create instances of this context based on the thread ID. + *

+ * + * @param sessionId Session that this context belongs to. + * @param processDmc The process that this thread belongs to. + * @param id thread identifier. + */ + protected MIThreadDMC(String sessionId, IProcessDMContext processDmc, String id) { + super(sessionId, processDmc != null ? new IDMContext[] { processDmc } : new IDMContext[0]); + fOSId = id; + } + + /** + * Returns the thread identifier of this context. + * @return + */ + public String getId(){ return fOSId; } + + @Override + public String toString() { return baseToString() + ".thread[" + fOSId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && ((MIThreadDMC)obj).fOSId == fOSId; + } + + @Override + public int hashCode() { return super.baseHashCode() ^ (fOSId == null ? 0 : fOSId.hashCode()); } + } + + @Immutable + protected class MIProcessDMC extends MIThreadDMC + implements IMIProcessDMContext + { + /** + * Constructor for the context. It should not be called directly by clients. + * Instead clients should call {@link MIProcesses#createProcessContext} + * to create instances of this context based on the PID. + *

+ * + * @param sessionId Session that this context belongs to. + * @param id process identifier. + */ + protected MIProcessDMC(String sessionId, String id) { + super(sessionId, null, id); + } + + public String getProcId() { return getId(); } + + @Override + public String toString() { return baseToString() + ".proc[" + getId() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public int hashCode() { return super.hashCode(); } + } + + /* + * The data of a corresponding thread or process. + */ + @Immutable + protected static class MIThreadDMData implements IThreadDMData { + final String fName; + final String fId; + + public MIThreadDMData(String name, String id) { + fName = name; + fId = id; + } + + public String getId() { return fId; } + public String getName() { return fName; } + public boolean isDebuggerAttached() { + return true; + } + } + + private ICommandControl fCommandControl; + + public MIProcesses(DsfSession session) { + super(session); + } + + /** + * This method initializes this service. + * + * @param requestMonitor + * The request monitor indicating the operation is finished + */ + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + /** + * This method initializes this service after our superclass's initialize() + * method succeeds. + * + * @param requestMonitor + * The call-back object to notify when this service's + * initialization is done. + */ + private void doInitialize(RequestMonitor requestMonitor) { + +// // Register this service. +// register(new String[] { IProcesses.class.getName(), +// MIProcesses.class.getName() }, +// new Hashtable()); + + fCommandControl = getServicesTracker().getService(ICommandControl.class); + + requestMonitor.done(); + } + + /** + * This method shuts down this service. It unregisters the service, stops + * receiving service events, and calls the superclass shutdown() method to + * finish the shutdown process. + * + * @return void + */ + @Override + public void shutdown(RequestMonitor requestMonitor) { +// unregister(); + super.shutdown(requestMonitor); + } + + /** + * @return The bundle context of the plug-in to which this service belongs. + */ + @Override + protected BundleContext getBundleContext() { + return MIPlugin.getBundleContext(); + } + + /** + * Create a thread context. + * + * @param processDmc The parent process context + * @param threadId The OS Id of the thread + */ + public IThreadDMContext createThreadContext(IProcessDMContext processDmc, String threadId) { + return new MIThreadDMC(getSession().getId(), processDmc, threadId); + } + + /** + * Create a process context. + * + * @param pid The OS Id of the process + */ + public IProcessDMContext createProcessContext(String pid) { + return new MIProcessDMC(getSession().getId(), pid); + } + + /** + * Create a executionGroup context. + * + * @param containerDmc The parent container context of this context + * @param processDmc The parent process context of this context + * @param groupId The thread group id of the process + */ + public IMIExecutionGroupDMContext createExecutionGroupContext(IContainerDMContext containerDmc, + IProcessDMContext processDmc, + String groupId) { + return new MIExecutionGroupDMC(getSession().getId(), containerDmc, processDmc, groupId); + } + + public IMIExecutionGroupDMContext createExecutionGroupContext(IContainerDMContext containerDmc, String groupId) { + return createExecutionGroupContext(containerDmc, createProcessContext(""), groupId); //$NON-NLS-1$ + } + + /** + * This method obtains the model data for a given GdbThreadDMC object + * which can represent a thread or a process. + * + * @param dmc + * The context for which we are requesting the data + * @param rm + * The request monitor that will contain the requested data + */ + @SuppressWarnings("unchecked") + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IThreadDMContext) { + getExecutionData((IThreadDMContext) dmc, + (DataRequestMonitor) rm); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + + public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor rm) { + // We must first do the if check for MIProcessDMC because it is also a GMIThreadDMC + if (dmc instanceof MIProcessDMC) { + rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getId())); //$NON-NLS-1$ + rm.done(); + } else if (dmc instanceof MIThreadDMC) { + rm.setData(new MIThreadDMData("", ((MIThreadDMC)dmc).getId())); //$NON-NLS-1$ + rm.done(); + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void attachDebuggerToProcess(IProcessDMContext procCtx, final DataRequestMonitor rm) { + if (procCtx instanceof IMIProcessDMContext) { + fCommandControl.queueCommand( + new CLIAttach((IMIProcessDMContext)procCtx), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + rm.setData(null); + rm.done(); + } + }); + + } else { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void detachDebuggerFromProcess(IProcessDMContext procCtx, final RequestMonitor rm) { +// if (procCtx instanceof MIProcessDMC) { +// int pid; +// try { +// pid = Integer.parseInt(((MIProcessDMC)procCtx).getId()); +// } catch (NumberFormatException e) { +// rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid process id.", null)); //$NON-NLS-1$ +// rm.done(); +// return; +// } +// +// // The service version cannot use -target-detach because it didn't exist +// // in versions of GDB up to and including GDB 6.8 +// fCommandControl.queueCommand( +// new CLIDetach(procCtx, pid), +// new DataRequestMonitor(getExecutor(), rm)); +// } else { +// rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$ +// rm.done(); +// } + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void canTerminate(IThreadDMContext thread, DataRequestMonitor rm) { + rm.setData(true); + rm.done(); + } + + public void debugNewProcess(String file, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor rm) { + // This service version only handles a single process to debug, therefore, we can simply + // create the context describing this process ourselves. This context's content is not + // used since it is the only context of its kind (only one process to debug) and can be recognized that way. + IContainerDMContext parentDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class); + IContainerDMContext containerDmc = createExecutionGroupContext(parentDmc, createProcessContext(""), "");//$NON-NLS-1$//$NON-NLS-2$ + rm.setData(new IContainerDMContext[] {containerDmc}); + rm.done(); + } + + public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void runNewProcess(String file, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void terminate(IThreadDMContext thread, RequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, + NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java index 455e15420c9..71229ade9fc 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java @@ -28,6 +28,9 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.MIProcesses; import org.eclipse.dd.mi.service.command.commands.CLICommand; import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; import org.eclipse.dd.mi.service.command.events.MIBreakpointChangedEvent; @@ -57,10 +60,13 @@ public class CLIEventProcessor // Last Thread ID created private static int fLastThreadId; + private final DsfServicesTracker fServicesTracker; + public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) { fCommandControl = connection; fInferior = inferior; fContainerDmc = containerDmc; + fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId()); connection.addCommandListener(this); connection.addEventListener(this); // Re-set the counter @@ -69,7 +75,8 @@ public class CLIEventProcessor public void dispose() { fCommandControl.removeCommandListener(this); - fCommandControl.removeEventListener(this); + fCommandControl.removeEventListener(this); + fServicesTracker.dispose(); } public void resetInferior(MIInferiorProcess inferior) { @@ -115,9 +122,16 @@ public class CLIEventProcessor Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$ Matcher matcher = pattern.matcher(exec.getCString()); if (matcher.find()) { - MIEvent e = new MIThreadCreatedEvent(fContainerDmc, ++fLastThreadId); + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + MIEvent e = new MIThreadCreatedEvent(processContainerDmc, ++fLastThreadId); fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties()); } + + // For GDB thread exit events, we won't use the events generated by GDB. This event is + // raised in GDBRunControl class by polling and comparing the ExecutionContexts returned by + // -thread-list-ids command. This is done as threads reported by exit event are still reported till + // they completely exit the system. } } @@ -130,8 +144,10 @@ public class CLIEventProcessor if (fInferior != null && "error".equals(state)) { //$NON-NLS-1$ if (fInferior.getState() == MIInferiorProcess.State.RUNNING) { fInferior.setState(MIInferiorProcess.State.STOPPED); + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ fCommandControl.getSession().dispatchEvent( - MIErrorEvent.parse(fContainerDmc, rr.getToken(), rr.getMIResults(), null), + MIErrorEvent.parse(processContainerDmc, rr.getToken(), rr.getMIResults(), null), fCommandControl.getProperties()); } } @@ -171,7 +187,9 @@ public class CLIEventProcessor int type = getSteppingOperationKind(operation); if (type != -1) { // if it was a step instruction set state running - MIEvent event = new MIRunningEvent(fContainerDmc, token, type); + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + MIEvent event = new MIRunningEvent(processContainerDmc, token, type); fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java index 8437b9fe801..662adaeef29 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java @@ -15,6 +15,7 @@ import java.util.LinkedList; import java.util.List; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; @@ -22,8 +23,8 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.mi.internal.MIPlugin; -import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.mi.service.IMIRunControl; +import org.eclipse.dd.mi.service.MIProcesses; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecFinish; import org.eclipse.dd.mi.service.command.commands.MIExecNext; @@ -64,7 +65,10 @@ import org.eclipse.dd.mi.service.command.output.MIValue; public class MIRunControlEventProcessor implements IEventListener, ICommandListener { - /** + private static final String STOPPED_REASON = "stopped"; //$NON-NLS-1$ + private static final String RUNNING_REASON = "running"; //$NON-NLS-1$ + + /** * The connection service that this event processor is registered with. */ private final AbstractMIControl fCommandControl; @@ -75,9 +79,6 @@ public class MIRunControlEventProcessor */ private final IContainerDMContext fContainerDmc; - /** - * Services tracker used to retrieve the MIRunControl service. - */ private final DsfServicesTracker fServicesTracker; /** @@ -105,7 +106,6 @@ public class MIRunControlEventProcessor public void eventReceived(Object output) { for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { - List> events = new LinkedList>(); if (oobr instanceof MIExecAsyncOutput) { MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr; // Change of state. @@ -116,73 +116,103 @@ public class MIRunControlEventProcessor fCommandControl.resetCurrentThreadLevel(); fCommandControl.resetCurrentStackLevel(); + String threadId = null; + // For now, since GDB does not support thread-groups, fake an empty one + String groupId = "";//null; //$NON-NLS-1$ + // I'm putting support for multiple reasons because it was + // there before, but I'm not sure this can actually happen + List reasons = new LinkedList(); MIResult[] results = exec.getMIResults(); for (int i = 0; i < results.length; i++) { String var = results[i].getVariable(); MIValue val = results[i].getMIValue(); if (var.equals("reason")) { //$NON-NLS-1$ if (val instanceof MIConst) { - String reason = ((MIConst) val).getString(); - MIEvent e = createEvent(reason, exec); - if (e != null) { - events.add(e); - continue; - } + reasons.add(((MIConst) val).getString()); + } + } else if (var.equals("thread-id")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + threadId = ((MIConst)val).getString(); + } + } else if (var.equals("group-id")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + groupId = ((MIConst)val).getString(); } } } - // We were stopped for some unknown reason, for example - // GDB for temporary breakpoints will not send the - // "reason" ??? still fire a stopped event. - if (events.isEmpty()) { - MIEvent e = MIStoppedEvent.parse( - fServicesTracker.getService(IMIRunControl.class), fContainerDmc, exec.getToken(), exec.getMIResults()); - events.add(e); - } - for (MIEvent event : events) { - fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); - } + // We were stopped for some unknown reason, for example + // GDB for temporary breakpoints will not send the + // "reason" ??? still fire a stopped event. + if (reasons.isEmpty()) { + reasons.add(STOPPED_REASON); + } + for (String reason : reasons) { + MIEvent event = createEvent(reason, exec, threadId, groupId); + if (event != null) { + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } + } } else if ("running".equals(state)) { //$NON-NLS-1$ - int token = exec.getToken(); + + String threadId = null; + // For now, since GDB does not support thread-groups, fake an empty one + String groupId = "";//null; //$NON-NLS-1$ + MIResult[] results = exec.getMIResults(); for (int i = 0; i < results.length; i++) { String var = results[i].getVariable(); MIValue val = results[i].getMIValue(); if (var.equals("thread-id")) { //$NON-NLS-1$ if (val instanceof MIConst) { - String thread = ((MIConst) val).getString(); - MIEvent evt = null; - int threadId = 0; - try { - threadId = Integer.parseInt(thread); - IMIExecutionDMContext context = fServicesTracker.getService(IMIRunControl.class).createMIExecutionContext(fContainerDmc, threadId); - evt = new MIRunningEvent(context, token, MIRunningEvent.CONTINUE); - } - catch (NumberFormatException e) { - evt = new MIRunningEvent(fContainerDmc, token, MIRunningEvent.CONTINUE); - - } - fCommandControl.getSession().dispatchEvent(evt, fCommandControl.getProperties()); + threadId = ((MIConst) val).getString(); + } + } else if (var.equals("group-id")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + groupId = ((MIConst)val).getString(); } } } - } - } - else if (oobr instanceof MINotifyAsyncOutput) { + MIEvent event = createEvent(RUNNING_REASON, exec, threadId, groupId); + if (event != null) { + fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + } + } + } else if (oobr instanceof MINotifyAsyncOutput) { // Parse the string and dispatch the corresponding event MINotifyAsyncOutput exec = (MINotifyAsyncOutput) oobr; String miEvent = exec.getAsyncClass(); - if ("thread-created".equals(miEvent)) { //$NON-NLS-1$ - MIEvent event = MIThreadCreatedEvent.parse(fContainerDmc, exec.getToken(), exec.getMIResults()); - if (event != null) { - fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); + if ("thread-created".equals(miEvent) || "thread-exited".equals(miEvent)) { //$NON-NLS-1$ //$NON-NLS-2$ + + // For now, since GDB does not support thread-groups, fake an empty one + String groupId = "";//null; //$NON-NLS-1$ + + MIResult[] results = exec.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue val = results[i].getMIValue(); + if (var.equals("group-id")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + groupId = ((MIConst) val).getString(); + } + } } - } - else if ("thread-exited".equals(miEvent)) { //$NON-NLS-1$ - MIEvent event = MIThreadExitEvent.parse(fContainerDmc, exec.getToken(), exec.getMIResults()); + + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + IContainerDMContext processContainerDmc = fContainerDmc; + if (procService != null && groupId != null) { + processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, groupId); + } + + MIEvent event = null; + if ("thread-created".equals(miEvent)) { //$NON-NLS-1$ + event = MIThreadCreatedEvent.parse(processContainerDmc, exec.getToken(), exec.getMIResults()); + } else if ("thread-exited".equals(miEvent)) { //$NON-NLS-1$ + event = MIThreadExitEvent.parse(processContainerDmc, exec.getToken(), exec.getMIResults()); + } + if (event != null) { fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); } @@ -191,6 +221,7 @@ public class MIRunControlEventProcessor } } + @Deprecated protected MIEvent createEvent(String reason, MIExecAsyncOutput exec) { IMIRunControl runControl = fServicesTracker.getService(IMIRunControl.class); MIEvent event = null; @@ -218,6 +249,58 @@ public class MIRunControlEventProcessor } return event; } + + protected MIEvent createEvent(String reason, MIExecAsyncOutput exec, String threadId, String groupId) { + IMIRunControl runControl = fServicesTracker.getService(IMIRunControl.class); + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + + IExecutionDMContext execDmc = fContainerDmc; + if (procService != null && groupId != null) { + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, groupId); + + execDmc = processContainerDmc; + if (runControl != null && threadId != null) { + int threadIdInt = -1; + try { + threadIdInt = Integer.parseInt(threadId); + } catch (NumberFormatException e) { + } + if (threadIdInt != -1) { + execDmc = runControl.createMIExecutionContext(processContainerDmc, threadIdInt); + } + } + } + + MIEvent event = null; + if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$ + event = MIBreakpointHitEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ( + "watchpoint-trigger".equals(reason) //$NON-NLS-1$ + || "read-watchpoint-trigger".equals(reason) //$NON-NLS-1$ + || "access-watchpoint-trigger".equals(reason)) { //$NON-NLS-1$ + event = MIWatchpointTriggerEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("watchpoint-scope".equals(reason)) { //$NON-NLS-1$ + event = MIWatchpointScopeEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("end-stepping-range".equals(reason)) { //$NON-NLS-1$ + event = MISteppingRangeEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("signal-received".equals(reason)) { //$NON-NLS-1$ + event = MISignalEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("location-reached".equals(reason)) { //$NON-NLS-1$ + event = MILocationReachedEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("function-finished".equals(reason)) { //$NON-NLS-1$ + event = MIFunctionFinishedEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if ("exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$ + event = MIInferiorExitEvent.parse(fCommandControl.getControlDMContext(), exec.getToken(), exec.getMIResults()); + } else if ("exited-signalled".equals(reason)) { //$NON-NLS-1$ + event = MIInferiorSignalExitEvent.parse(fCommandControl.getControlDMContext(), exec.getToken(), exec.getMIResults()); + } else if (STOPPED_REASON.equals(reason)) { + event = MIStoppedEvent.parse(execDmc, exec.getToken(), exec.getMIResults()); + } else if (RUNNING_REASON.equals(reason)) { + event = new MIRunningEvent(execDmc, exec.getToken(), MIRunningEvent.CONTINUE); + } + return event; + } + public void commandQueued(ICommandToken token) { // Do nothing. @@ -254,9 +337,12 @@ public class MIRunControlEventProcessor else if (cmd instanceof MIExecReturn) { type = MIRunningEvent.RETURN; } else if (cmd instanceof MIExecContinue) { type = MIRunningEvent.CONTINUE; } else { type = MIRunningEvent.CONTINUE; } - + + MIProcesses procService = fServicesTracker.getService(MIProcesses.class); + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + fCommandControl.getSession().dispatchEvent( - new MIRunningEvent(fContainerDmc, id, type), fCommandControl.getProperties()); + new MIRunningEvent(processContainerDmc, id, type), fCommandControl.getProperties()); } else if ("exit".equals(state)) { //$NON-NLS-1$ // No need to do anything, terminate() will. // Send exited? diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java index 9edf0bfd92e..b728da7a04a 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java @@ -1,13 +1,12 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 QNX Software Systems and others. + * Copyright (c) 2008 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: - * QNX Software Systems - Initial API and implementation - * Ericsson - Modified for new DSF Reference Implementation + * Ericsson - Initial API and implementation *******************************************************************************/ package org.eclipse.dd.mi.service.command.commands; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java index cfdc217e6d7..383f57fec62 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java @@ -39,6 +39,7 @@ public class MIBreakpointHitEvent extends MIStoppedEvent { return bkptno; } + @Deprecated public static MIBreakpointHitEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -62,4 +63,27 @@ public class MIBreakpointHitEvent extends MIStoppedEvent { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MIBreakpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno); } + + public static MIBreakpointHitEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + int bkptno = -1; + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value != null && value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("bkptno")) { //$NON-NLS-1$ + try { + bkptno = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MIBreakpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java index 0ba43986fc3..e4c9922bfcc 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java @@ -53,6 +53,7 @@ public class MIFunctionFinishedEvent extends MIStoppedEvent { return returnType; } + @Deprecated public static MIFunctionFinishedEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -80,4 +81,31 @@ public class MIFunctionFinishedEvent extends MIStoppedEvent { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MIFunctionFinishedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), gdbResult, returnValue, returnType); } + + public static MIFunctionFinishedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + String gdbResult = ""; //$NON-NLS-1$ + String returnValue = ""; //$NON-NLS-1$ + String returnType = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("gdb-result-var")) { //$NON-NLS-1$ + gdbResult = str; + } else if (var.equals("return-value")) { //$NON-NLS-1$ + returnValue = str; + } else if (var.equals("return-type")) { //$NON-NLS-1$ + returnType = str; + } + } + + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MIFunctionFinishedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), gdbResult, returnValue, returnType); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java index 46d2f1fd874..9883b8c787d 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java @@ -28,11 +28,18 @@ public class MILocationReachedEvent extends MIStoppedEvent { protected MILocationReachedEvent(IExecutionDMContext ctx, int token, MIResult[] results, MIFrame frame) { super(ctx, token, results, frame); } - + + @Deprecated public static MILocationReachedEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MILocationReachedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); } + + public static MILocationReachedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MILocationReachedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java index dbf174374c1..09d1586c692 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java @@ -29,6 +29,7 @@ public class MISharedLibEvent extends MIStoppedEvent { super(ctx, token, results, frame); } + @Deprecated public static MIStoppedEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -36,4 +37,10 @@ public class MISharedLibEvent extends MIStoppedEvent { return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); } + public static MIStoppedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } + } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java index ad540dc9606..f7c822a3f05 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java @@ -48,6 +48,8 @@ public class MISignalEvent extends MIStoppedEvent { return sigMeaning; } + + @Deprecated public static MISignalEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -72,4 +74,28 @@ public class MISignalEvent extends MIStoppedEvent { return new MISignalEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), sigName, sigMeaning); } + + public static MISignalEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + String sigName = ""; //$NON-NLS-1$ + String sigMeaning = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + String str = ""; //$NON-NLS-1$ + if (value instanceof MIConst) { + str = ((MIConst)value).getString(); + } + + if (var.equals("signal-name")) { //$NON-NLS-1$ + sigName = str; + } else if (var.equals("signal-meaning")) { //$NON-NLS-1$ + sigMeaning = str; + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MISignalEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), sigName, sigMeaning); + } + } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java index 35a3005b01a..13018bc0ab4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java @@ -30,10 +30,17 @@ public class MISteppingRangeEvent extends MIStoppedEvent { super(ctx, token, results, frame); } + @Deprecated public static MISteppingRangeEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MISteppingRangeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); + } + + public static MISteppingRangeEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MISteppingRangeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java index 509669ef30e..e8c4c9a2aea 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java @@ -40,6 +40,7 @@ public class MIStoppedEvent extends MIEvent { return frame; } + @Deprecated public static MIStoppedEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -70,4 +71,21 @@ public class MIStoppedEvent extends MIEvent { } return new MIStoppedEvent(execDmc, token, results, frame); } + + public static MIStoppedEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + MIFrame frame = null; + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("frame")) { //$NON-NLS-1$ + if (value instanceof MITuple) { + frame = new MIFrame((MITuple)value); + } + } + } + return new MIStoppedEvent(dmc, token, results, frame); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java index 26822656d3e..645f127772b 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java @@ -41,6 +41,7 @@ public class MIWatchpointScopeEvent extends MIStoppedEvent { return number; } + @Deprecated public static MIWatchpointScopeEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -63,4 +64,26 @@ public class MIWatchpointScopeEvent extends MIStoppedEvent { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MIWatchpointScopeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number); } + + public static MIWatchpointScopeEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + int number = 0; + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("wpnum")) { //$NON-NLS-1$ + if (value instanceof MIConst) { + String str = ((MIConst) value).getString(); + try { + number = Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + } + } + } + } + + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MIWatchpointScopeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java index c7346565c58..dbf6c7bfd73 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java @@ -61,6 +61,7 @@ public class MIWatchpointTriggerEvent extends MIStoppedEvent { return newValue; } + @Deprecated public static MIWatchpointTriggerEvent parse( IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) { @@ -119,4 +120,62 @@ public class MIWatchpointTriggerEvent extends MIStoppedEvent { MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); return new MIWatchpointTriggerEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number, exp, oldValue, newValue); } + + public static MIWatchpointTriggerEvent parse(IExecutionDMContext dmc, int token, MIResult[] results) + { + int number = 0; + String exp = ""; //$NON-NLS-1$ + String oldValue = ""; //$NON-NLS-1$ + String newValue = ""; //$NON-NLS-1$ + + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue value = results[i].getMIValue(); + + if (var.equals("wpt") || var.equals("hw-awpt") || var.equals("hw-rwpt")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (value instanceof MITuple) { + for (MIResult wptResult : ((MITuple) value).getMIResults()) { + String wptVar = wptResult.getVariable(); + MIValue wptValue = wptResult.getMIValue(); + + if (wptVar.equals("number")) { //$NON-NLS-1$ + if (wptValue instanceof MIConst) { + String str = ((MIConst) wptValue).getString(); + try { + number = Integer.parseInt(str); + } catch (NumberFormatException e) { + } + } + } else if (wptVar.equals("exp")) { //$NON-NLS-1$ + if (wptValue instanceof MIConst) { + exp = ((MIConst) wptValue).getString(); + } + } + } + } + } else if (var.equals("value")) { //$NON-NLS-1$ + if (value instanceof MITuple) { + for (MIResult valueResult : ((MITuple)value).getMIResults()) { + String valueVar = valueResult.getVariable(); + MIValue valueValue = valueResult.getMIValue(); + String str = ""; //$NON-NLS-1$ + if (valueValue instanceof MIConst) { + str = ((MIConst) valueValue).getString(); + } + + if (valueVar.equals("old")) { //$NON-NLS-1$ + oldValue = str; + } else if (valueVar.equals("new")) { //$NON-NLS-1$ + newValue = str; + } else if (valueVar.equals("value")) { //$NON-NLS-1$ + oldValue = newValue = str; + } + } + + } + } + } + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + return new MIWatchpointTriggerEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), number, exp, oldValue, newValue); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java index c5fe86759ec..ef2b377eecf 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java @@ -1,13 +1,12 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 QNX Software Systems and others. + * Copyright (c) 2008 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: - * QNX Software Systems - Initial API and implementation - * Ericsson AB - Modified for DSF Reference Implementation + * Ericsson - Initial API and implementation *******************************************************************************/ package org.eclipse.dd.mi.service.command.output;