From 0db5876d624d7853e5169a34f3b5d809b0d7b8c8 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 25 Jul 2008 19:37:00 +0000 Subject: [PATCH] Bug 239050 This patch adds more usage of the IProcesses service. I believe the patch is backwards compatible with our 1.0 release (not with the latest HEAD). The patch does the following: 1- cleanup context hierarchy to become: MIControlDMContext | MIProcessDMC (IProcess) MIExecutionGroupDMC __/ | (IContainer) | | MIThreadDMC (IThread) MIExecutionDMC _____/ (IExecution) Notice how I put MIControlDMContext at the top. The create*DMC methods have been updated accordingly. The constructors of the MI*DMC classes have been updated accordingly. 2- Deprecated GDBRunControl.getThreadData() and GDBRunControl.getProcessData() and have GdbThreadFilterEditor and ThreadVMNode use IProcesses instead. 3- because of (2) I was able to remove IGDBRunControl and GDBRunControlNS completely. 4- Made MIProcesses.getExecutionData() fetch the thread data using CLIInfoThreads as is done (but deprecated) in GDBRunControl.getThreadData() 5- Added a cache and event listeners to MIProcesses to cache CLIInfoThreads. 6- Update MIRunControlEventProcessor and CLIEventProcessor to use MIControlDMContext as their top context instead of IContainerDMContext --- .../ui/breakpoints/GdbThreadFilterEditor.java | 17 +- .../ui/viewmodel/launch/ThreadVMNode.java | 38 ++-- .../launching/FinalLaunchSequence.java | 5 +- .../provisional/service/GDBProcesses.java | 13 +- .../provisional/service/GDBRunControl.java | 20 +- .../provisional/service/GDBRunControlNS.java | 129 ------------ .../service/GdbDebugServicesFactoryNS.java | 3 +- .../provisional/service/IGDBRunControl.java | 41 ---- .../eclipse/dd/mi/service/MIProcesses.java | 191 ++++++++++++------ .../eclipse/dd/mi/service/MIRunControl.java | 43 +++- .../eclipse/dd/mi/service/MIRunControlNS.java | 4 + .../mi/service/command/CLIEventProcessor.java | 18 +- .../command/MIRunControlEventProcessor.java | 39 ++-- .../service/command/commands/CLIAttach.java | 10 +- .../command/commands/CLIInfoThreads.java | 5 + .../dd/tests/gdb/GDBProcessesTest.java | 16 +- 16 files changed, 267 insertions(+), 325 deletions(-) delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java delete mode 100644 plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java index 0f576ee2f9e..695fc47fa03 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java @@ -24,14 +24,15 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IProcesses; import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension; import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; import org.eclipse.dd.mi.service.IMIExecutionDMContext; @@ -493,12 +494,14 @@ public class GdbThreadFilterEditor { return; } - ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IGDBRunControl.class + ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IProcesses.class .getName(), null); tracker.open(); - IGDBRunControl runControl = (IGDBRunControl) tracker.getService(); - if (runControl != null) { - runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor( + IProcesses procService = (IProcesses) tracker.getService(); + if (procService != null) { + IThreadDMContext threadDmc = DMContexts.getAncestorOfType(thread, IThreadDMContext.class); + procService.getExecutionData(threadDmc, new DataRequestMonitor( + // Is it ok to use the ImmediateExecutor here? ImmediateExecutor.getInstance(), rm) { @Override protected void handleSuccess() { @@ -513,7 +516,7 @@ public class GdbThreadFilterEditor { } }); } else { - rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$ + rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "IProcesses service not accessible.")); //$NON-NLS-1$ rm.done(); } tracker.close(); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java index 5b97341e037..fd6b1e67042 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java @@ -13,16 +13,17 @@ package org.eclipse.dd.gdb.internal.ui.viewmodel.launch; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.AbstractThreadVMNode; -import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IProcesses; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor; 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.IGDBThreadData; import org.eclipse.dd.mi.service.IMIExecutionDMContext; +import org.eclipse.dd.mi.service.IMIRunControl; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; @@ -49,24 +50,27 @@ public class ThreadVMNode extends AbstractThreadVMNode @Override protected void updateLabelInSessionThread(ILabelUpdate[] updates) { for (final ILabelUpdate update : updates) { - final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); - if ( runControl == null ) { + final IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class); + if (runControl == null) { handleFailedUpdate(update); continue; } - final IMIExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class); + final IMIExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class); String imageKey = null; - if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + final boolean threadSuspended; + if (runControl.isSuspended(execDmc)) { + threadSuspended = true; imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; } else { + threadSuspended = false; imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; } update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); // Find the Reason for the State - runControl.getExecutionData(dmc, + runControl.getExecutionData(execDmc, new ViewerDataRequestMonitor(getSession().getExecutor(), update) { @Override public void handleCompleted(){ @@ -76,10 +80,8 @@ public class ThreadVMNode extends AbstractThreadVMNode return; } - // We're in a new dispatch cycle, and we have to check whether the - // service reference is still valid. - final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); - if ( runControl == null ) { + final IProcesses procService = getServicesTracker().getService(IProcesses.class); + if ( procService == null ) { handleFailedUpdate(update); return; } @@ -87,9 +89,11 @@ public class ThreadVMNode extends AbstractThreadVMNode final StateChangeReason reason = getData().getStateChangeReason(); // Retrieve the rest of the thread information - runControl.getThreadData( - dmc, - new ViewerDataRequestMonitor(getSession().getExecutor(), update) { + final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class); + + procService.getExecutionData( + threadDmc, + new ViewerDataRequestMonitor(getSession().getExecutor(), update) { @Override public void handleCompleted() { if (!isSuccess()) { @@ -99,11 +103,11 @@ public class ThreadVMNode extends AbstractThreadVMNode // Create Labels of type Thread[GDBthreadId]RealThreadID/Name (State: Reason) // Thread[1] 3457 (Suspended:BREAKPOINT) final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ - builder.append(dmc.getThreadId()); + builder.append(execDmc.getThreadId()); builder.append("] "); //$NON-NLS-1$ builder.append(getData().getId()); builder.append(getData().getName()); - if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) + if(threadSuspended) builder.append(" (Suspended"); //$NON-NLS-1$ else builder.append(" (Running"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index e6f6a89fde7..8c4d27b3726 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -393,7 +393,8 @@ public class FinalLaunchSequence extends Sequence { try { Object result = prompter.handleStatus(processPromptStatus, fProcessList); if (result instanceof Integer) { - fRequestMonitor.setData(fProcService.createProcessContext(Integer.toString((Integer)result))); + fRequestMonitor.setData(fProcService.createProcessContext(fCommandControl.getGDBDMContext(), + Integer.toString((Integer)result))); } else { fRequestMonitor.setStatus(NO_PID_STATUS); } @@ -420,7 +421,7 @@ public class FinalLaunchSequence extends Sequence { if (pid != -1) { fProcService.attachDebuggerToProcess( - fProcService.createProcessContext(Integer.toString(pid)), + fProcService.createProcessContext(fCommandControl.getGDBDMContext(), Integer.toString(pid)), new DataRequestMonitor(getExecutor(), requestMonitor)); } else { fProcService.getRunningProcesses( 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 afdf4079101..17f61fbe84a 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 @@ -22,6 +22,7 @@ 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.RequestMonitor; +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.service.DsfSession; @@ -29,6 +30,7 @@ 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.MIProcesses; +import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.MIInferiorProcess; import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses; import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo; @@ -97,7 +99,7 @@ public class GDBProcesses extends MIProcesses { public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor rm) { // We must first check for GdbProcessDMC because it is also a GdbThreadDMC if (dmc instanceof MIProcessDMC) { - String pidStr = ((MIProcessDMC)dmc).getId(); + String pidStr = ((MIProcessDMC)dmc).getProcId(); int pid = -1; try { pid = Integer.parseInt(pidStr); @@ -126,6 +128,7 @@ public class GDBProcesses extends MIProcesses { @Override public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor rm) { + final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class); if (fGdb.getSessionType() == SessionType.LOCAL) { IProcessList list = null; try { @@ -142,7 +145,7 @@ public class GDBProcesses extends MIProcesses { for (IProcessInfo procInfo : list.getProcessList()) { fProcessNames.put(procInfo.getPid(), procInfo.getName()); } - rm.setData(makeProcessDMCs(list.getProcessList())); + rm.setData(makeProcessDMCs(controlDmc, list.getProcessList())); } rm.done(); } else { @@ -156,7 +159,7 @@ public class GDBProcesses extends MIProcesses { for (IProcessInfo procInfo : getData().getProcessList()) { fProcessNames.put(procInfo.getPid(), procInfo.getName()); } - rm.setData(makeProcessDMCs(getData().getProcessList())); + rm.setData(makeProcessDMCs(controlDmc, getData().getProcessList())); } else { // The monitor list command is not supported. // Just return an empty list and let the caller deal with it. @@ -170,10 +173,10 @@ public class GDBProcesses extends MIProcesses { } } - private IProcessDMContext[] makeProcessDMCs(IProcessInfo[] processes) { + private IProcessDMContext[] makeProcessDMCs(MIControlDMContext controlDmc, IProcessInfo[] processes) { IProcessDMContext[] procDmcs = new MIProcessDMC[processes.length]; for (int i=0; i()); + GDBRunControl.class.getName()}, new Hashtable()); requestMonitor.done(); } @@ -152,15 +153,16 @@ public class GDBRunControl extends MIRunControl implements IGDBRunControl { super.getExecutionContexts(c, rm1); } - public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor rm) { + @Deprecated + public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor rm) { rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) ); rm.done(); } - public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor rm) { - IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class); - assert containerDmc != null; // Every exec context should have a container as an ancestor. - getCache().execute(new CLIInfoThreads(containerDmc), + @Deprecated + public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor rm) { + IProcessDMContext prodDmc = DMContexts.getAncestorOfType(execDmc, IProcessDMContext.class); + getCache().execute(new CLIInfoThreads(prodDmc), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java deleted file mode 100644 index f93482d4286..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River 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: - * Wind River Systems - initial API and implementation - * Ericsson AB - Modified for additional functionality - *******************************************************************************/ - -package org.eclipse.dd.gdb.internal.provisional.service; - - -import java.util.Hashtable; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.service.DsfSession; -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.IMIExecutionDMContext; -import org.eclipse.dd.mi.service.IMIRunControl; -import org.eclipse.dd.mi.service.MIRunControlNS; -import org.eclipse.dd.mi.service.command.commands.MIThreadInfo; -import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo; - -public class GDBRunControlNS extends MIRunControlNS implements IGDBRunControl -{ - /** - * Implement a custom execution data for threads in order to provide additional - * information. This object can be made separate from IExecutionDMData after - * the deprecated method: IDMService.getModelData() is no longer used. - */ - private static class GDBThreadData implements IGDBThreadData { - private final String fId; - private final String fName; - - GDBThreadData(String id, String name) { - fId = id; - fName = name; - } - - public String getName() { - return fName; - } - public String getId() { return fId; } - - public boolean isDebuggerAttached() { return true; } - } - - /** - * Implement a custom execution data the process in order to provide additional - * information. This object can be made separate from IExecutionDMData after - * the deprecated method: IDMService.getModelData() is no longer used. - */ - private static class GDBProcessData implements IGDBProcessData { - private final String fName; - - GDBProcessData(String name) { - fName = name; - } - - public String getName() { - return fName; - } - } - - private GDBControl fGdb; - - public GDBRunControlNS(DsfSession session) { - super(session); - } - - @Override - public void initialize(final RequestMonitor requestMonitor) { - super.initialize( - new RequestMonitor(getExecutor(), requestMonitor) { - @Override - public void handleSuccess() { - doInitialize(requestMonitor); - }}); - } - - private void doInitialize(final RequestMonitor requestMonitor) { - - fGdb = getServicesTracker().getService(GDBControl.class); - register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName(), IGDBRunControl.class.getName()}, new Hashtable()); - - requestMonitor.done(); - } - - @Override - public void shutdown(final RequestMonitor requestMonitor) { - unregister(); - super.shutdown(requestMonitor); - } - - public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor rm) { - rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) ); - rm.done(); - } - - public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor rm) { - IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class); - getCache().execute(new MIThreadInfo(containerDmc, execDmc.getThreadId()), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleSuccess() { - rm.setData(createThreadInfo(execDmc, getData())); - rm.done(); - } - }); - } - - private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, MIThreadInfoInfo info) { - // There should be only 1 thread in the result, but just in case... - for (MIThreadInfoInfo.ThreadInfo thread : info.getThreadInfoList()) { - if (Integer.parseInt(thread.getGdbId()) == dmc.getThreadId()){ - return new GDBThreadData(thread.getOsId(), ""); //$NON-NLS-1$ - } - } - return new GDBThreadData("", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - -} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java index 5ba6a8ff947..354328b8298 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java @@ -13,6 +13,7 @@ package org.eclipse.dd.gdb.internal.provisional.service; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.mi.service.MIRunControlNS; import org.eclipse.dd.mi.service.MIStackNS; public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory { @@ -28,6 +29,6 @@ public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory { @Override protected IRunControl createRunControlService(DsfSession session) { - return new GDBRunControlNS(session); + return new MIRunControlNS(session); } } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java deleted file mode 100644 index 53c8e10b075..00000000000 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River 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: - * Wind River Systems - initial API and implementation - * Ericsson - Modified for additional functionality - *******************************************************************************/ -package org.eclipse.dd.gdb.internal.provisional.service; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext; -import org.eclipse.dd.mi.service.IMIExecutionDMContext; -import org.eclipse.dd.mi.service.IMIRunControl; - -/** - * This interface provides access to controlling and monitoring the execution - * state of a process being debugged. This interface does not actually - * provide methods for creating or destroying execution contexts, it doesn't - * even have methods for getting labels. That's because it is expected that - * higher level services, ones that deal with processes, kernels, or target - * features will provide that functionality. - */ -public interface IGDBRunControl extends IMIRunControl -{ - public interface IGDBThreadData { - public String getName(); - public String getId(); - public boolean isDebuggerAttached(); - } - - public interface IGDBProcessData { - public String getName(); - } - - public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor rm); - public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor dataRequestMonitor); -} 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 index 17c473dd5fb..3c42060b56e 100644 --- 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 @@ -20,17 +20,40 @@ 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.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; import org.eclipse.dd.dsf.service.AbstractDsfService; +import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; +import org.eclipse.dd.mi.service.command.AbstractMIControl; +import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.commands.CLIAttach; +import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads; +import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; import org.osgi.framework.BundleContext; public class MIProcesses extends AbstractDsfService implements IProcesses { - /* + + // Below is the context hierarchy that is implemented between the + // MIProcesses service and the MIRunControl service for the MI + // implementation of DSF: + // + // MIControlDMContext + // | + // MIProcessDMC (IProcess) + // MIExecutionGroupDMC __/ | + // (IContainer) | + // | MIThreadDMC (IThread) + // MIExecutionDMC _____/ + // (IExecution) + // + + /** * Context representing a thread group of GDB/MI. */ @Immutable @@ -48,16 +71,11 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { * 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 processDmc The process context that 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 }); + protected MIExecutionGroupDMC(String sessionId, IProcessDMContext processDmc, String groupId) { + super(sessionId, processDmc == null ? new IDMContext[0] : new IDMContext[] { processDmc }); fId = groupId; } @@ -71,21 +89,25 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { @Override public boolean equals(Object obj) { - return super.baseEquals(obj) && ((MIExecutionGroupDMC)obj).fId.equals(fId); + return super.baseEquals(obj) && + (((MIExecutionGroupDMC)obj).fId == null ? fId == null : ((MIExecutionGroupDMC)obj).fId.equals(fId)); } @Override - public int hashCode() { return super.baseHashCode() + fId.hashCode(); } + public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } } + /** + * Context representing a thread. + */ @Immutable protected class MIThreadDMC extends AbstractDMContext implements IThreadDMContext { /** - * ID given by the OS. + * ID used by GDB to refer to threads. */ - private final String fOSId; + private final String fId; /** * Constructor for the context. It should not be called directly by clients. @@ -98,32 +120,38 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { * @param id thread identifier. */ protected MIThreadDMC(String sessionId, IProcessDMContext processDmc, String id) { - super(sessionId, processDmc != null ? new IDMContext[] { processDmc } : new IDMContext[0]); - fOSId = id; + super(sessionId, processDmc == null ? new IDMContext[0] : new IDMContext[] { processDmc }); + fId = id; } /** * Returns the thread identifier of this context. * @return */ - public String getId(){ return fOSId; } + public String getId(){ return fId; } @Override - public String toString() { return baseToString() + ".OSthread[" + fOSId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + public String toString() { return baseToString() + ".OSthread[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - @Override - public boolean equals(Object obj) { - return super.baseEquals(obj) && ((MIThreadDMC)obj).fOSId.equals(fOSId); - } + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && + (((MIThreadDMC)obj).fId == null ? fId == null : ((MIThreadDMC)obj).fId.equals(fId)); + } - @Override - public int hashCode() { return super.baseHashCode() ^ (fOSId == null ? 0 : fOSId.hashCode()); } + @Override + public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } } @Immutable - protected class MIProcessDMC extends MIThreadDMC + protected class MIProcessDMC extends AbstractDMContext implements IMIProcessDMContext { + /** + * ID given by the OS. + */ + private final String fId; + /** * Constructor for the context. It should not be called directly by clients. * Instead clients should call {@link MIProcesses#createProcessContext} @@ -131,26 +159,29 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { *

* * @param sessionId Session that this context belongs to. + * @param controlDmc The control context parent of this process. * @param id process identifier. */ - protected MIProcessDMC(String sessionId, String id) { - super(sessionId, null, id); + protected MIProcessDMC(String sessionId, MIControlDMContext controlDmc, String id) { + super(sessionId, controlDmc == null ? new IDMContext[0] : new IDMContext[] { controlDmc }); + fId = id; } - public String getProcId() { return getId(); } + public String getProcId() { return fId; } @Override - public String toString() { return baseToString() + ".proc[" + getId() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + public String toString() { return baseToString() + ".proc[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - @Override - public boolean equals(Object obj) { - return super.equals(obj); - } + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && + (((MIProcessDMC)obj).fId == null ? fId == null : ((MIProcessDMC)obj).fId.equals(fId)); + } - @Override - public int hashCode() { return super.hashCode(); } + @Override + public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } } - + /* * The data of a corresponding thread or process. */ @@ -171,7 +202,8 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { } } - private ICommandControl fCommandControl; + private AbstractMIControl fCommandControl; + private CommandCache fCommandCache; public MIProcesses(DsfSession session) { super(session); @@ -208,8 +240,11 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { // MIProcesses.class.getName() }, // new Hashtable()); - fCommandControl = getServicesTracker().getService(ICommandControl.class); - + fCommandControl = getServicesTracker().getService(AbstractMIControl.class); + fCommandCache = new CommandCache(getSession(), fCommandControl); + fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true); + getSession().addServiceEventListener(this, null); + requestMonitor.done(); } @@ -223,6 +258,7 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { @Override public void shutdown(RequestMonitor requestMonitor) { // unregister(); + getSession().removeServiceEventListener(this); super.shutdown(requestMonitor); } @@ -249,29 +285,23 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { * * @param pid The OS Id of the process */ - public IProcessDMContext createProcessContext(String pid) { - return new MIProcessDMC(getSession().getId(), pid); + public IProcessDMContext createProcessContext(MIControlDMContext controlDmc, String pid) { + return new MIProcessDMC(getSession().getId(), controlDmc, 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, + public IMIExecutionGroupDMContext createExecutionGroupContext(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$ + return new MIExecutionGroupDMC(getSession().getId(), processDmc, groupId); } /** - * This method obtains the model data for a given GdbThreadDMC object + * This method obtains the model data for a given IThreadDMContext object * which can represent a thread or a process. * * @param dmc @@ -285,23 +315,37 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { 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.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid 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 + public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor rm) { if (dmc instanceof MIProcessDMC) { - rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getId())); //$NON-NLS-1$ + rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getProcId())); //$NON-NLS-1$ rm.done(); } else if (dmc instanceof MIThreadDMC) { - rm.setData(new MIThreadDMData("", ((MIThreadDMC)dmc).getId())); //$NON-NLS-1$ - rm.done(); + final MIThreadDMC threadDmc = (MIThreadDMC)dmc; + + IProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IProcessDMContext.class); + fCommandCache.execute(new CLIInfoThreads(procDmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + IThreadDMData threadData = new MIThreadDMData("", ""); //$NON-NLS-1$ //$NON-NLS-2$ + for (CLIInfoThreadsInfo.ThreadInfo thread : getData().getThreadInfo()) { + if (thread.getId().equals(threadDmc.getId())) { + threadData = new MIThreadDMData(thread.getName(), thread.getOsId()); + break; + } + } + rm.setData(threadData); + rm.done(); + } + }); } else { - rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); + rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ + rm.done(); } } @@ -318,8 +362,9 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { public void attachDebuggerToProcess(IProcessDMContext procCtx, final DataRequestMonitor rm) { if (procCtx instanceof IMIProcessDMContext) { + MIControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, MIControlDMContext.class); fCommandControl.queueCommand( - new CLIAttach((IMIProcessDMContext)procCtx), + new CLIAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()), new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { @@ -382,11 +427,10 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { 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}); + // create the context describing this process ourselves. + MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class); + IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(createProcessContext(controlDmc, ""), "");//$NON-NLS-1$//$NON-NLS-2$ + rm.setData(new IContainerDMContext[] {groupDmc}); rm.done(); } @@ -400,7 +444,6 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { rm.setData(false); 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$ @@ -412,4 +455,20 @@ public class MIProcesses extends AbstractDsfService implements IProcesses { NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ rm.done(); } + + @DsfServiceEventHandler + public void eventDispatched(IResumedDMEvent e) { + fCommandCache.setContextAvailable(e.getDMContext(), false); + fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true); + if (e.getReason() != StateChangeReason.STEP) { + fCommandCache.reset(); + } + } + + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + fCommandCache.setContextAvailable(e.getDMContext(), true); + fCommandCache.reset(); + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java index 7ff3c184644..d82ed1354a2 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java @@ -21,6 +21,8 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.command.CommandCache; import org.eclipse.dd.dsf.service.AbstractDsfService; @@ -72,7 +74,7 @@ import org.osgi.framework.BundleContext; */ public class MIRunControl extends AbstractDsfService implements IMIRunControl { - class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext + protected class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext { /** * Integer ID that is used to identify the thread in the GDB/MI protocol. @@ -89,10 +91,26 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl * * @param sessionId Session that this context belongs to. * @param containerDmc The container that this context belongs to. + * @param threadDmc The thread context parents of this context. * @param threadId GDB/MI thread identifier. */ + protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, IThreadDMContext threadDmc, int threadId) { + super(sessionId, + containerDmc == null && threadDmc == null ? new IDMContext[0] : + containerDmc == null ? new IDMContext[] { threadDmc } : + threadDmc == null ? new IDMContext[] { containerDmc } : + new IDMContext[] { containerDmc, threadDmc }); + fThreadId = threadId; + } + protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) { - super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]); + super(sessionId, + containerDmc == null ? new IDMContext[0] + : new IDMContext[] { containerDmc, + fProcService.createThreadContext(DMContexts.getAncestorOfType(containerDmc, + IProcessDMContext.class), + Integer.toString(threadId)) }); + fThreadId = threadId; } @@ -274,6 +292,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl private AbstractMIControl fConnection; private CommandCache fMICommandCache; + private MIProcesses fProcService; // State flags private boolean fSuspended = true; @@ -304,6 +323,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl fConnection = getServicesTracker().getService(AbstractMIControl.class); fMICommandCache = new CommandCache(getSession(), fConnection); fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true); + fProcService = getServicesTracker().getService(MIProcesses.class); getSession().addServiceEventListener(this, null); rm.done(); } @@ -330,7 +350,16 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl public CommandCache getCache() { return fMICommandCache; } public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) { - return new MIExecutionDMC(getSession().getId(), container, threadId); + MIProcesses procService = getServicesTracker().getService(MIProcesses.class); + IProcessDMContext procDmc = DMContexts.getAncestorOfType(container, IProcessDMContext.class); + + IThreadDMContext threadDmc = null; + if (procService != null && procDmc != null) { + // For now, reuse the threadId as the OSThreadId + threadDmc = procService.createThreadContext(procDmc, Integer.toString(threadId)); + } + + return new MIExecutionDMC(getSession().getId(), container, threadDmc, threadId); } // @@ -376,7 +405,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl @DsfServiceEventHandler public void eventDispatched(final MIThreadCreatedEvent e) { IContainerDMContext containerDmc = e.getDMContext(); - IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; + IMIExecutionDMContext executionCtx = e.getId() != -1 ? createMIExecutionContext(containerDmc, e.getId()) : null; getSession().dispatchEvent(new StartedDMEvent(executionCtx, e), getProperties()); } @@ -387,7 +416,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl @DsfServiceEventHandler public void eventDispatched(final MIThreadExitEvent e) { IContainerDMContext containerDmc = e.getDMContext(); - IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; + IMIExecutionDMContext executionCtx = e.getId() != -1 ? createMIExecutionContext(containerDmc, e.getId()) : null; getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties()); } @@ -628,11 +657,11 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl if (info.getThreadIds().length == 0) { //Main thread always exist even if it is not reported by GDB. //So create thread-id= 0 when no thread is reported - return new IMIExecutionDMContext[]{new MIExecutionDMC(getSession().getId(), containerCtx, DEFAULT_THREAD_ID)}; + return new IMIExecutionDMContext[]{createMIExecutionContext(containerCtx, DEFAULT_THREAD_ID)}; } else { IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length]; for (int i = 0; i < info.getThreadIds().length; i++) { - executionDmcs[i] = new MIExecutionDMC(getSession().getId(), containerCtx, info.getThreadIds()[i]); + executionDmcs[i] = createMIExecutionContext(containerCtx, info.getThreadIds()[i]); } return executionDmcs; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControlNS.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControlNS.java index c9d6ad899e7..a60eb7e17d2 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControlNS.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControlNS.java @@ -13,6 +13,7 @@ package org.eclipse.dd.mi.service; import java.util.HashMap; +import java.util.Hashtable; import java.util.Map; import org.eclipse.core.runtime.IStatus; @@ -25,6 +26,7 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.dd.dsf.debug.service.command.CommandCache; import org.eclipse.dd.dsf.service.AbstractDsfService; @@ -319,6 +321,7 @@ public class MIRunControlNS extends AbstractDsfService implements IMIRunControl } private void doInitialize(final RequestMonitor rm) { + register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName()}, new Hashtable()); fConnection = getServicesTracker().getService(AbstractMIControl.class); fMICommandCache = new CommandCache(getSession(), fConnection); fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true); @@ -328,6 +331,7 @@ public class MIRunControlNS extends AbstractDsfService implements IMIRunControl @Override public void shutdown(final RequestMonitor rm) { + unregister(); getSession().removeServiceEventListener(this); fMICommandCache.reset(); super.shutdown(rm); 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 71229ade9fc..167a485f1cc 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 @@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommandListener; @@ -54,7 +55,7 @@ public class CLIEventProcessor { private final AbstractMIControl fCommandControl; private MIInferiorProcess fInferior; - private final IContainerDMContext fContainerDmc; + private final MIControlDMContext fControlDmc; private final List fEventList = new LinkedList(); // Last Thread ID created @@ -65,7 +66,7 @@ public class CLIEventProcessor public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) { fCommandControl = connection; fInferior = inferior; - fContainerDmc = containerDmc; + fControlDmc = DMContexts.getAncestorOfType(containerDmc, MIControlDMContext.class); fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId()); connection.addCommandListener(this); connection.addEventListener(this); @@ -123,7 +124,8 @@ public class CLIEventProcessor Matcher matcher = pattern.matcher(exec.getCString()); if (matcher.find()) { MIProcesses procService = fServicesTracker.getService(MIProcesses.class); - IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$ MIEvent e = new MIThreadCreatedEvent(processContainerDmc, ++fLastThreadId); fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties()); } @@ -145,7 +147,8 @@ public class CLIEventProcessor 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$ + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$ fCommandControl.getSession().dispatchEvent( MIErrorEvent.parse(processContainerDmc, rr.getToken(), rr.getMIResults(), null), fCommandControl.getProperties()); @@ -157,7 +160,7 @@ public class CLIEventProcessor private void processStateChanges(CLICommand cmd) { String operation = cmd.getOperation().trim(); - // In refactoring we are no longer genwerating the token id as + // In refactoring we are no longer generating the token id as // part of the command. It is passed here and stored away and // then never really used. So it has just been changed to 0. processStateChanges(0, operation); @@ -166,7 +169,7 @@ public class CLIEventProcessor private void processStateChanges(MIInterpreterExecConsole exec) { String[] operations = exec.getParameters(); if (operations != null && operations.length > 0) { - // In refactoring we are no longer genwerating the token id as + // In refactoring we are no longer generating the token id as // part of the command. It is passed here and stored away and // then never really used. So it has just been changed to 0. processStateChanges(0, operations[0]); @@ -188,7 +191,8 @@ public class CLIEventProcessor if (type != -1) { // if it was a step instruction set state running MIProcesses procService = fServicesTracker.getService(MIProcesses.class); - IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$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 c2546058a94..f87e0b5123e 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 @@ -14,6 +14,8 @@ package org.eclipse.dd.mi.service.command; import java.util.LinkedList; import java.util.List; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext; 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; @@ -77,7 +79,7 @@ public class MIRunControlEventProcessor * Container context used as the context for the run control events generated * by this processor. */ - private final IContainerDMContext fContainerDmc; + private final MIControlDMContext fControlDmc; private final DsfServicesTracker fServicesTracker; @@ -89,7 +91,7 @@ public class MIRunControlEventProcessor */ public MIRunControlEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc) { fCommandControl = connection; - fContainerDmc = containerDmc; + fControlDmc = DMContexts.getAncestorOfType(containerDmc, MIControlDMContext.class); fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId()); connection.addEventListener(this); connection.addCommandListener(this); @@ -171,10 +173,8 @@ public class MIRunControlEventProcessor } MIProcesses procService = fServicesTracker.getService(MIProcesses.class); - IContainerDMContext processContainerDmc = fContainerDmc; - if (procService != null && groupId != null) { - processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, groupId); - } + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId); MIEvent event = null; if ("thread-created".equals(miEvent)) { //$NON-NLS-1$ @@ -216,20 +216,18 @@ public class MIRunControlEventProcessor 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); + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, 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); - } + IExecutionDMContext 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); } } @@ -300,7 +298,8 @@ public class MIRunControlEventProcessor else { type = MIRunningEvent.CONTINUE; } MIProcesses procService = fServicesTracker.getService(MIProcesses.class); - IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$ + IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$ + IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$ fCommandControl.getSession().dispatchEvent( new MIRunningEvent(processContainerDmc, id, type), fCommandControl.getProperties()); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java index 7ddc37f401d..fbf0e9d1f9e 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java @@ -11,7 +11,7 @@ package org.eclipse.dd.mi.service.command.commands; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.mi.service.IMIProcessDMContext; +import org.eclipse.dd.mi.service.command.MIControlDMContext; import org.eclipse.dd.mi.service.command.output.MIInfo; /** @@ -19,13 +19,11 @@ import org.eclipse.dd.mi.service.command.output.MIInfo; */ public class CLIAttach extends CLICommand { - @Deprecated public CLIAttach(IDMContext ctx, int pid) { super(ctx, "attach " + Integer.toString(pid)); //$NON-NLS-1$ } - public CLIAttach(IMIProcessDMContext ctx) { - super(ctx, "attach " + ctx.getProcId()); //$NON-NLS-1$ + public CLIAttach(MIControlDMContext ctx, String pid) { + super(ctx, "attach " + pid); //$NON-NLS-1$ } - -} \ No newline at end of file +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java index c3cfecb8009..13b3a855b28 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIInfoThreads.java @@ -14,6 +14,7 @@ package org.eclipse.dd.mi.service.command.commands; +import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -30,6 +31,10 @@ public class CLIInfoThreads extends CLICommand { super(ctx, "info threads"); //$NON-NLS-1$ } + public CLIInfoThreads(IProcessDMContext ctx) { + super(ctx, "info threads"); //$NON-NLS-1$ + } + @Override public CLIInfoThreadsInfo getResult(MIOutput output) { return (CLIInfoThreadsInfo)getMIInfo(output); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java index 91d5e921374..930aaf98ed0 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java @@ -24,8 +24,8 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBProcessData; -import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData; +import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.mi.service.IMIExecutionDMContext; import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; @@ -91,8 +91,8 @@ public class GDBProcessesTest extends BaseTestCase { /* * Create a request monitor */ - final DataRequestMonitor rm = - new DataRequestMonitor(fSession.getExecutor(), null) { + final DataRequestMonitor rm = + new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -123,7 +123,7 @@ public class GDBProcessesTest extends BaseTestCase { /* * Get process data */ - IGDBProcessData processData = rm.getData(); + GDBProcessData processData = rm.getData(); if(processData == null) Assert.fail("No process data is returned for Process DMC"); @@ -141,8 +141,8 @@ public class GDBProcessesTest extends BaseTestCase { */ @Test public void getThreadData() throws InterruptedException{ - final DataRequestMonitor rm = - new DataRequestMonitor(fSession.getExecutor(), null) { + final DataRequestMonitor rm = + new DataRequestMonitor(fSession.getExecutor(), null) { @Override protected void handleCompleted() { if (isSuccess()) { @@ -166,7 +166,7 @@ public class GDBProcessesTest extends BaseTestCase { fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); assertTrue(fWait.getMessage(), fWait.isOK()); - IGDBThreadData threadData = rm.getData(); + GDBThreadData threadData = rm.getData(); if(threadData == null) fail("Thread data not returned for thread id = " + fExecDmc.getThreadId()); else{