Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 108117 Details for
Bug 237556
[non-stop] Add support for non-stop multi-threaded debugging in GDB.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Non-stop multi-threading patch
NonStopMultiThreading.patch (text/plain), 189.83 KB, created by
Francois Chouinard
on 2008-07-22 15:07:54 EDT
(
hide
)
Description:
Non-stop multi-threading patch
Filename:
MIME Type:
Creator:
Francois Chouinard
Created:
2008-07-22 15:07:54 EDT
Size:
189.83 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.dd.tests.gdb >Index: src/org/eclipse/dd/tests/gdb/AllTests.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/AllTests.java,v >retrieving revision 1.2 >diff -u -r1.2 AllTests.java >--- src/org/eclipse/dd/tests/gdb/AllTests.java 17 Jun 2008 16:16:19 -0000 1.2 >+++ src/org/eclipse/dd/tests/gdb/AllTests.java 22 Jul 2008 19:07:00 -0000 >@@ -26,7 +26,8 @@ > MIRunControlTest.class, > ExpressionServiceTest.class, > MIMemoryTest.class, >- MIBreakpointsTest.class >+ MIBreakpointsTest.class, >+ MIDisassemblyTest.class, > > /* Add your test class here */ > }) >Index: src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java,v >retrieving revision 1.4 >diff -u -r1.4 GDBProcessesTest.java >--- src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java 25 Jun 2008 17:57:45 -0000 1.4 >+++ src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java 22 Jul 2008 19:07:00 -0000 >@@ -24,8 +24,8 @@ > 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.GDBRunControl.GDBProcessData; >-import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; >+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.command.GDBControl; > import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor; >@@ -91,8 +91,8 @@ > /* > * Create a request monitor > */ >- final DataRequestMonitor<GDBProcessData> rm = >- new DataRequestMonitor<GDBProcessData>(fSession.getExecutor(), null) { >+ final DataRequestMonitor<IGDBProcessData> rm = >+ new DataRequestMonitor<IGDBProcessData>(fSession.getExecutor(), null) { > @Override > protected void handleCompleted() { > if (isSuccess()) { >@@ -123,7 +123,7 @@ > /* > * Get process data > */ >- GDBProcessData processData = rm.getData(); >+ IGDBProcessData processData = rm.getData(); > > if(processData == null) > Assert.fail("No process data is returned for Process DMC"); >@@ -141,8 +141,8 @@ > */ > @Test > public void getThreadData() throws InterruptedException{ >- final DataRequestMonitor<GDBThreadData> rm = >- new DataRequestMonitor<GDBThreadData>(fSession.getExecutor(), null) { >+ final DataRequestMonitor<IGDBThreadData> rm = >+ new DataRequestMonitor<IGDBThreadData>(fSession.getExecutor(), null) { > @Override > protected void handleCompleted() { > if (isSuccess()) { >@@ -166,7 +166,7 @@ > fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER); > assertTrue(fWait.getMessage(), fWait.isOK()); > >- GDBThreadData threadData = rm.getData(); >+ IGDBThreadData threadData = rm.getData(); > if(threadData == null) > fail("Thread data not returned for thread id = " + fExecDmc.getThreadId()); > else{ >#P org.eclipse.dd.dsf.debug >Index: src/org/eclipse/dd/dsf/debug/service/IRunControl.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRunControl.java,v >retrieving revision 1.15 >diff -u -r1.15 IRunControl.java >--- src/org/eclipse/dd/dsf/debug/service/IRunControl.java 30 May 2008 22:57:44 -0000 1.15 >+++ src/org/eclipse/dd/dsf/debug/service/IRunControl.java 22 Jul 2008 19:07:00 -0000 >@@ -37,7 +37,7 @@ > > /** > * Context representing a process, kernel, or some other logical container >- * for execution cotnexts, which by itself can perform run-control >+ * for execution contexts, which by itself can perform run-control > * operations. > */ > >Index: src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java,v >retrieving revision 1.23 >diff -u -r1.23 DsfMemoryBlockRetrieval.java >--- src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java 30 May 2008 22:57:44 -0000 1.23 >+++ src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java 22 Jul 2008 19:07:00 -0000 >@@ -379,8 +379,9 @@ > public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { > // Drill for the actual DMC > IMemoryDMContext memoryDmc = null; >+ IDMContext dmc = null; > if (context instanceof IAdaptable) { >- IDMContext dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); >+ dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class); > if (dmc != null) { > memoryDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class); > } >@@ -425,7 +426,7 @@ > // In case of failure, simply return 'null' > > // Resolve the expression >- blockAddress = resolveMemoryAddress(memoryDmc, expression); >+ blockAddress = resolveMemoryAddress(dmc, expression); > if (blockAddress == null) { > return null; > } >@@ -451,7 +452,7 @@ > // Helper functions > /////////////////////////////////////////////////////////////////////////// > >- private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException { >+ private BigInteger resolveMemoryAddress(final IDMContext dmc, final String expression) throws DebugException { > > // Use a Query to "synchronize" the downstream calls > Query<BigInteger> query = new Query<BigInteger>() { >@@ -461,7 +462,7 @@ > final IExpressions expressionService = (IExpressions) fExpressionServiceTracker.getService(); > if (expressionService != null) { > // Create the expression >- final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression); >+ final IExpressionDMContext expressionDMC = expressionService.createExpression(dmc, expression); > String formatId = IFormattedValues.HEX_FORMAT; > FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId); > expressionService.getFormattedExpressionValue( >#P org.eclipse.dd.gdb.ui >Index: src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java,v >retrieving revision 1.15 >diff -u -r1.15 ThreadVMNode.java >--- src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java 17 Jun 2008 20:46:29 -0000 1.15 >+++ src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java 22 Jul 2008 19:07:01 -0000 >@@ -20,8 +20,8 @@ > 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.GDBRunControl; >-import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; >+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.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; > import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; >@@ -49,7 +49,7 @@ > @Override > protected void updateLabelInSessionThread(ILabelUpdate[] updates) { > for (final ILabelUpdate update : updates) { >- final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); >+ final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); > if ( runControl == null ) { > handleFailedUpdate(update); > continue; >@@ -78,7 +78,7 @@ > > // We're in a new dispatch cycle, and we have to check whether the > // service reference is still valid. >- final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); >+ final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); > if ( runControl == null ) { > handleFailedUpdate(update); > return; >@@ -89,7 +89,7 @@ > // Retrieve the rest of the thread information > runControl.getThreadData( > dmc, >- new ViewerDataRequestMonitor<GDBThreadData>(getSession().getExecutor(), update) { >+ new ViewerDataRequestMonitor<IGDBThreadData>(getSession().getExecutor(), update) { > @Override > public void handleCompleted() { > if (!isSuccess()) { >Index: src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java,v >retrieving revision 1.16 >diff -u -r1.16 ContainerVMNode.java >--- src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java 17 Jun 2008 20:46:28 -0000 1.16 >+++ src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java 22 Jul 2008 19:07:01 -0000 >@@ -25,8 +25,8 @@ > 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.GDBRunControl; >-import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData; >+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; >@@ -72,7 +72,7 @@ > > @Override > protected void updateLabelInSessionThread(final ILabelUpdate update) { >- final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); >+ final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); > if ( runControl == null ) { > handleFailedUpdate(update); > return; >@@ -90,7 +90,7 @@ > > runControl.getProcessData( > dmc, >- new ViewerDataRequestMonitor<GDBProcessData>(getExecutor(), update) { >+ new ViewerDataRequestMonitor<IGDBProcessData>(getExecutor(), update) { > @Override > public void handleCompleted() { > if (!isSuccess()) { >@@ -151,11 +151,11 @@ > try { > getSession().getExecutor().execute(new DsfRunnable() { > public void run() { >- final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); >+ final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); > if ( runControl != null ) { > runControl.getProcessData( > procDmc, >- new ViewerDataRequestMonitor<GDBProcessData>(runControl.getExecutor(), request) { >+ new ViewerDataRequestMonitor<IGDBProcessData>(runControl.getExecutor(), request) { > @Override > protected void handleCompleted() { > if ( getStatus().isOK() ) { >@@ -203,11 +203,11 @@ > try { > getSession().getExecutor().execute(new DsfRunnable() { > public void run() { >- final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class); >+ final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class); > if ( runControl != null ) { > runControl.getProcessData( > procDmc, >- new ViewerDataRequestMonitor<GDBProcessData>(runControl.getExecutor(), request) { >+ new ViewerDataRequestMonitor<IGDBProcessData>(runControl.getExecutor(), request) { > @Override > protected void handleCompleted() { > if ( getStatus().isOK() ) { >Index: src/org/eclipse/dd/gdb/internal/ui/launching/GdbDebuggerPage.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbDebuggerPage.java,v >retrieving revision 1.1 >diff -u -r1.1 GdbDebuggerPage.java >--- src/org/eclipse/dd/gdb/internal/ui/launching/GdbDebuggerPage.java 22 May 2008 20:23:15 -0000 1.1 >+++ src/org/eclipse/dd/gdb/internal/ui/launching/GdbDebuggerPage.java 22 Jul 2008 19:07:01 -0000 >@@ -45,6 +45,7 @@ > protected TabFolder fTabFolder; > protected Text fGDBCommandText; > protected Text fGDBInitText; >+ protected Button fNonStopCheckBox; > private IMILaunchConfigurationComponent fSolibBlock; > private boolean fIsInitializing = false; > >@@ -64,6 +65,9 @@ > IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT); > configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, > IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT); >+ configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, >+ IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); >+ > if (fSolibBlock != null) > fSolibBlock.setDefaults(configuration); > } >@@ -86,6 +90,8 @@ > setInitializing(true); > String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT; > String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT; >+ boolean nonStopMode = IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT; >+ > try { > gdbCommand = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, > IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT); >@@ -99,10 +105,18 @@ > catch(CoreException e) { > } > >+ try { >+ nonStopMode = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, >+ IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); >+ } >+ catch(CoreException e) { >+ } >+ > if (fSolibBlock != null) > fSolibBlock.initializeFrom(configuration); > fGDBCommandText.setText(gdbCommand); > fGDBInitText.setText(gdbInit); >+ fNonStopCheckBox.setSelection(nonStopMode); > > setInitializing(false); > } >@@ -112,6 +126,8 @@ > fGDBCommandText.getText().trim()); > configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, > fGDBInitText.getText().trim()); >+ configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, >+ fNonStopCheckBox.getSelection()); > > if (fSolibBlock != null) > fSolibBlock.performApply(configuration); >@@ -242,8 +258,23 @@ > fGDBInitText.setText(res); > } > }); >+ >+ // TODO: Fetch the string from LaunchUIMessages >+ // TODO: Ideally, this field should be disabled if the back-end doesn't support non-stop debugging >+ // TODO: Find a way to determine if non-stop is supported (i.e. find the GDB version) then grey out the check box if necessary >+ // Button fNonStopButton = ControlFactory.createCheckBox(subComp, LaunchUIMessages.getString( "GDBDebuggerPage.15") ); //$NON-NLS-1$ >+ fNonStopCheckBox = ControlFactory.createCheckBox(subComp, LaunchUIMessages.getString("GDBDebuggerPage.13")); //$NON-NLS-1$ >+ fNonStopCheckBox.setEnabled(false); >+ fNonStopCheckBox.addSelectionListener( new SelectionAdapter() { >+ @Override >+ public void widgetSelected(SelectionEvent e) { >+ updateLaunchConfigurationDialog(); >+ } >+ }); >+ > label = ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.9"), //$NON-NLS-1$ > 200, SWT.DEFAULT, SWT.WRAP); >+ > gd = new GridData(GridData.FILL_HORIZONTAL); > gd.horizontalSpan = 3; > gd.widthHint = 200; >Index: src/org/eclipse/dd/gdb/internal/ui/launching/LaunchUIMessages.properties >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/LaunchUIMessages.properties,v >retrieving revision 1.2 >diff -u -r1.2 LaunchUIMessages.properties >--- src/org/eclipse/dd/gdb/internal/ui/launching/LaunchUIMessages.properties 6 Jun 2008 15:07:12 -0000 1.2 >+++ src/org/eclipse/dd/gdb/internal/ui/launching/LaunchUIMessages.properties 22 Jul 2008 19:07:01 -0000 >@@ -24,6 +24,7 @@ > GDBDebuggerPage.10=Shared Libraries > GDBDebuggerPage.11=Protocol: > GDBDebuggerPage.12=Default >+GDBDebuggerPage.13=Non-stop mode (Note: Requires non-stop GDB) > StandardGDBDebuggerPage.0=Debugger executable must be specified. > StandardGDBDebuggerPage.1=GDB Debugger Options > StandardGDBDebuggerPage.2=Main >Index: src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java,v >retrieving revision 1.6 >diff -u -r1.6 GdbThreadFilterEditor.java >--- src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java 28 Mar 2008 15:42:15 -0000 1.6 >+++ src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java 22 Jul 2008 19:07:01 -0000 >@@ -30,8 +30,8 @@ > 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.GDBRunControl; >-import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData; >+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 +493,12 @@ > return; > } > >- ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), GDBRunControl.class >+ ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IGDBRunControl.class > .getName(), null); > tracker.open(); >- GDBRunControl runControl = (GDBRunControl) tracker.getService(); >+ IGDBRunControl runControl = (IGDBRunControl) tracker.getService(); > if (runControl != null) { >- runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor<GDBThreadData>( >+ runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor<IGDBThreadData>( > ImmediateExecutor.getInstance(), rm) { > @Override > protected void handleSuccess() { >#P org.eclipse.dd.gdb >Index: src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java,v >retrieving revision 1.3 >diff -u -r1.3 GDBRunControl.java >--- src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java 2 Jun 2008 18:13:23 -0000 1.3 >+++ src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java 22 Jul 2008 19:07:02 -0000 >@@ -29,19 +29,21 @@ > 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.MIRunControl; > import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads; > import org.eclipse.dd.mi.service.command.events.MIEvent; > import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent; > import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo; >-public class GDBRunControl extends MIRunControl { > >- /** >+public class GDBRunControl extends MIRunControl 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. > */ >- public static class GDBThreadData { >+ public static class GDBThreadData implements IGDBThreadData { > private final String fId; > private final String fName; > >@@ -63,7 +65,7 @@ > * information. This object can be made separate from IExecutionDMData after > * the deprecated method: IDMService.getModelData() is no longer used. > */ >- public static class GDBProcessData { >+ public static class GDBProcessData implements IGDBProcessData { > private final String fName; > > GDBProcessData(String name) { >@@ -74,7 +76,7 @@ > return fName; > } > } >- >+ > private GDBControl fGdb; > > // Record list of execution contexts >@@ -98,8 +100,9 @@ > private void doInitialize(final RequestMonitor requestMonitor) { > > fGdb = getServicesTracker().getService(GDBControl.class); >- register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>()); >- >+ register(new String[]{IRunControl.class.getName(), >+ IMIRunControl.class.getName(), MIRunControl.class.getName(), >+ IGDBRunControl.class.getName(), GDBRunControl.class.getName()}, new Hashtable<String,String>()); > requestMonitor.done(); > } > >@@ -149,12 +152,12 @@ > super.getExecutionContexts(c, rm1); > } > >- public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<GDBProcessData> rm) { >+ public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) { > rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) ); > rm.done(); > } > >- public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<GDBThreadData> rm) { >+ public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> 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), >Index: src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java,v >retrieving revision 1.17 >diff -u -r1.17 GdbLaunchDelegate.java >--- src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java 24 Jun 2008 18:41:39 -0000 1.17 >+++ src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java 22 Jul 2008 19:07:02 -0000 >@@ -37,6 +37,7 @@ > import org.eclipse.dd.gdb.internal.GdbPlugin; > import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; > import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactory; >+import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactoryNS; > import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; > import org.eclipse.debug.core.DebugException; > import org.eclipse.debug.core.ILaunch; >@@ -56,7 +57,9 @@ > { > public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ > >- public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { >+ private boolean isNonStopSession = false; >+ >+ public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException { > if ( monitor == null ) { > monitor = new NullProgressMonitor(); > } >@@ -167,6 +170,16 @@ > return SessionType.LOCAL; > } > >+ private boolean isNonStopSession(ILaunchConfiguration config) { >+ try { >+ boolean nonStopMode = config.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, >+ IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); >+ return nonStopMode; >+ } catch (CoreException e) { >+ } >+ return false; >+ } >+ > private boolean getIsAttach(ILaunchConfiguration config) { > try { > String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); >@@ -202,6 +215,8 @@ > // the adapters will be created for the whole session, including > // the source lookup adapter. > >+ isNonStopSession = isNonStopSession(configuration); >+ > GdbLaunch launch = new GdbLaunch(configuration, mode, null); > launch.initialize(); > launch.setSourceLocator(getSourceLocator(configuration, launch.getSession())); >@@ -314,6 +329,12 @@ > } > > private IDsfDebugServicesFactory newServiceFactory(String version) { >+ >+ // TODO: Fix version number once non-stop GDB is delivered >+ if (isNonStopSession && version.startsWith("6.8.50.20080327")) { //$NON-NLS-1$ >+ return new GdbDebugServicesFactoryNS(version); >+ } >+ > if (version.startsWith("6.6") || //$NON-NLS-1$ > version.startsWith("6.7") || //$NON-NLS-1$ > version.startsWith("6.8")) { //$NON-NLS-1$ >Index: src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java,v >retrieving revision 1.5 >diff -u -r1.5 IGDBLaunchConfigurationConstants.java >--- src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java 22 May 2008 20:23:13 -0000 1.5 >+++ src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java 22 Jul 2008 19:07:02 -0000 >@@ -49,6 +49,12 @@ > public static final String ATTR_GDB_INIT = GdbPlugin.PLUGIN_ID + ".GDB_INIT"; //$NON-NLS-1$ > > /** >+ * Launch configuration attribute key. Boolean value to set the non-stop mode >+ * Debuger/gdb/MI property. >+ */ >+ public static final String ATTR_DEBUGGER_NON_STOP = GdbPlugin.PLUGIN_ID + ".NON_STOP"; //$NON-NLS-1$ >+ >+ /** > * Launch configuration attribute key. Boolean value to set the 'automatically load shared library symbols' flag of the debugger. > */ > public static final String ATTR_DEBUGGER_AUTO_SOLIB = GdbPlugin.PLUGIN_ID + ".AUTO_SOLIB"; //$NON-NLS-1$ >@@ -79,6 +85,11 @@ > public static final String DEBUGGER_GDB_INIT_DEFAULT = ".gdbinit"; //$NON-NLS-1$ > > /** >+ * Launch configuration attribute value. The key is ATTR_DEBUGGER_NON_STOP. >+ */ >+ public static final boolean DEBUGGER_NON_STOP_DEFAULT = false; >+ >+ /** > * Launch configuration attribute value. The key is ATTR_DEBUGGER_AUTO_SOLIB. > */ > public static final boolean DEBUGGER_AUTO_SOLIB_DEFAULT = true; >Index: src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java,v >retrieving revision 1.14 >diff -u -r1.14 GDBControl.java >--- src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java 23 Jun 2008 15:35:12 -0000 1.14 >+++ src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java 22 Jul 2008 19:07:02 -0000 >@@ -179,7 +179,7 @@ > * More strongly typed version of {@link #getControlDMContext()}. > */ > public GDBControlDMContext getGDBDMContext() { >- return (GDBControlDMContext)getControlDMContext(); >+ return (GDBControlDMContext) getControlDMContext(); > } > > public SessionType getSessionType() { >Index: src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java >=================================================================== >RCS file: src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java >diff -N src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * 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<IGDBProcessData> rm); >+ public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> dataRequestMonitor); >+} >Index: src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java >=================================================================== >RCS file: src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java >diff -N src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+/******************************************************************************* >+ * 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.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.MIStackNS; >+ >+public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory { >+ >+ public GdbDebugServicesFactoryNS(String version) { >+ super(version); >+ } >+ >+ @Override >+ protected IStack createStackService(DsfSession session) { >+ return new MIStackNS(session); >+ } >+ >+ @Override >+ protected IRunControl createRunControlService(DsfSession session) { >+ return new GDBRunControlNS(session); >+ } >+} >Index: src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java >=================================================================== >RCS file: src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java >diff -N src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,129 @@ >+/******************************************************************************* >+ * 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<String,String>()); >+ >+ requestMonitor.done(); >+ } >+ >+ @Override >+ public void shutdown(final RequestMonitor requestMonitor) { >+ unregister(); >+ super.shutdown(requestMonitor); >+ } >+ >+ public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) { >+ rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) ); >+ rm.done(); >+ } >+ >+ public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> rm) { >+ IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class); >+ getCache().execute(new MIThreadInfo(containerDmc, execDmc.getThreadId()), >+ new DataRequestMonitor<MIThreadInfoInfo>(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$ >+ } >+ >+} >#P org.eclipse.dd.mi >Index: src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIBreakpointHitEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -40,7 +40,7 @@ > } > > public static MIBreakpointHitEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > int bkptno = -1; > >Index: src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MILocationReachedEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; > >@@ -30,7 +30,7 @@ > } > > public static MILocationReachedEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ 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()); >Index: src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIThreadCreatedEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java 13 Feb 2008 20:34:29 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -14,6 +14,9 @@ > > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; >+import org.eclipse.dd.mi.service.command.output.MIConst; >+import org.eclipse.dd.mi.service.command.output.MIResult; >+import org.eclipse.dd.mi.service.command.output.MIValue; > > > /** >@@ -37,4 +40,25 @@ > public int getId() { > return tid; > } >+ >+ public static MIThreadCreatedEvent parse(IContainerDMContext ctx, int token, MIResult[] results) >+ { >+ for (int i = 0; i < results.length; i++) { >+ String var = results[i].getVariable(); >+ MIValue val = results[i].getMIValue(); >+ if (var.equals("id")) { //$NON-NLS-1$ >+ if (val instanceof MIConst) { >+ try { >+ int thread = Integer.parseInt(((MIConst) val).getString()); >+ return new MIThreadCreatedEvent(ctx, token, thread); >+ } >+ catch (NumberFormatException e) { >+ return null; >+ } >+ } >+ } >+ } >+ >+ return null; >+ } > } >Index: src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MISharedLibEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; > >@@ -30,7 +30,7 @@ > } > > public static MIStoppedEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); > return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame()); >Index: src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIThreadExitEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java 13 Feb 2008 20:34:29 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -14,6 +14,9 @@ > > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; >+import org.eclipse.dd.mi.service.command.output.MIConst; >+import org.eclipse.dd.mi.service.command.output.MIResult; >+import org.eclipse.dd.mi.service.command.output.MIValue; > > > /** >@@ -37,4 +40,25 @@ > public int getId() { > return tid; > } >+ >+ public static MIThreadExitEvent parse(IContainerDMContext ctx, int token, MIResult[] results) >+ { >+ for (int i = 0; i < results.length; i++) { >+ String var = results[i].getVariable(); >+ MIValue val = results[i].getMIValue(); >+ if (var.equals("id")) { //$NON-NLS-1$ >+ if (val instanceof MIConst) { >+ try { >+ int thread = Integer.parseInt(((MIConst) val).getString()); >+ return new MIThreadExitEvent(ctx, token, thread); >+ } >+ catch (NumberFormatException e) { >+ return null; >+ } >+ } >+ } >+ } >+ >+ return null; >+ } > } >Index: src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MISteppingRangeEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; > >@@ -31,7 +31,7 @@ > } > > public static MISteppingRangeEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ 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()); >Index: src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MISignalEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java 13 Feb 2008 20:34:29 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -49,7 +49,7 @@ > } > > public static MISignalEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > String sigName = ""; //$NON-NLS-1$ > String sigMeaning = ""; //$NON-NLS-1$ >Index: src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIWatchpointTriggerEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -62,7 +62,7 @@ > } > > public static MIWatchpointTriggerEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > int number = 0; > String exp = ""; //$NON-NLS-1$ >Index: src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStoppedEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -41,7 +41,7 @@ > } > > public static MIStoppedEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > int threadId = -1; > MIFrame frame = null; >Index: src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIFunctionFinishedEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java 13 Feb 2008 20:34:29 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -54,7 +54,7 @@ > } > > public static MIFunctionFinishedEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > String gdbResult = ""; //$NON-NLS-1$ > String returnValue = ""; //$NON-NLS-1$ >Index: src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java,v >retrieving revision 1.1 >diff -u -r1.1 MIWatchpointScopeEvent.java >--- src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java 13 Feb 2008 20:34:29 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java 22 Jul 2008 19:07:06 -0000 >@@ -15,7 +15,7 @@ > import org.eclipse.dd.dsf.concurrent.Immutable; > import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >-import org.eclipse.dd.mi.service.MIRunControl; >+import org.eclipse.dd.mi.service.IMIRunControl; > import org.eclipse.dd.mi.service.command.output.MIConst; > import org.eclipse.dd.mi.service.command.output.MIFrame; > import org.eclipse.dd.mi.service.command.output.MIResult; >@@ -42,7 +42,7 @@ > } > > public static MIWatchpointScopeEvent parse( >- MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) >+ IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) > { > int number = 0; > for (int i = 0; i < results.length; i++) { >Index: src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java,v >retrieving revision 1.1 >diff -u -r1.1 MIVarCreate.java >--- src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java 22 Jul 2008 19:07:05 -0000 >@@ -53,7 +53,7 @@ > this(dmc, "-", "*", expression); //$NON-NLS-1$ //$NON-NLS-2$ > } > >- public MIVarCreate(IExpressionDMContext dmc,String name, String expression) { >+ public MIVarCreate(IExpressionDMContext dmc, String name, String expression) { > this(dmc, name, "*", expression); //$NON-NLS-1$ > } > >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecStep.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java 22 Jul 2008 19:07:05 -0000 >@@ -14,11 +14,12 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** > * >- * -exec-step >+ * -exec-step [--thread <tid>] [count] > * > * Asynchronous command. Resumes execution of the inferior program, > * stopping when the beginning of the next source line is reached, if the >@@ -29,10 +30,23 @@ > public class MIExecStep extends MICommand<MIInfo> > { > public MIExecStep(IExecutionDMContext dmc) { >- super(dmc, "-exec-step"); //$NON-NLS-1$ >+ this(dmc, 1); > } > > public MIExecStep(IExecutionDMContext dmc, int count) { > super(dmc, "-exec-step", new String[] { Integer.toString(count) }); //$NON-NLS-1$ > } >+ >+ public MIExecStep(IMIExecutionDMContext dmc, boolean setThread) { >+ this(dmc, setThread, 1); >+ } >+ >+ public MIExecStep(IMIExecutionDMContext dmc, boolean setThread, int count) { >+ super(dmc, "-exec-step"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { Integer.toString(count) }); >+ } >+ } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecInterrupt.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java 22 Jul 2008 19:07:05 -0000 >@@ -14,11 +14,12 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** > * >- * -exec-interrupt >+ * -exec-interrupt [ --thread <tid> | --all ] > * > * Asynchronous command. Interrupts the background execution of the > * target. Note how the token associated with the stop message is the one >@@ -31,6 +32,20 @@ > public class MIExecInterrupt extends MICommand<MIInfo> > { > public MIExecInterrupt(IExecutionDMContext dmc) { >+ this(dmc, false); >+ } >+ >+ public MIExecInterrupt(IExecutionDMContext dmc, boolean allThreads) { >+ super(dmc, "-exec-interrupt"); //$NON-NLS-1$ >+ if (allThreads) { >+ setParameters(new String[] { "--all" }); //$NON-NLS-1$ >+ } >+ } >+ >+ public MIExecInterrupt(IMIExecutionDMContext dmc, boolean setThread) { > super(dmc, "-exec-interrupt"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()) }); //$NON-NLS-1$ >+ } > } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecNextInstruction.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java 22 Jul 2008 19:07:05 -0000 >@@ -13,6 +13,7 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** >@@ -28,10 +29,23 @@ > public class MIExecNextInstruction extends MICommand<MIInfo> > { > public MIExecNextInstruction(IExecutionDMContext dmc) { >- super(dmc, "-exec-next-instruction"); //$NON-NLS-1$ >+ this(dmc, 1); > } > > public MIExecNextInstruction(IExecutionDMContext dmc, int count) { > super(dmc, "-exec-next-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$ > } >+ >+ public MIExecNextInstruction(IMIExecutionDMContext dmc, boolean setThread) { >+ this(dmc, setThread, 1); >+ } >+ >+ public MIExecNextInstruction(IMIExecutionDMContext dmc, boolean setThread, int count) { >+ super(dmc, "-exec-next-instruction"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { Integer.toString(count) }); >+ } >+ } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecStepInstruction.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java 22 Jul 2008 19:07:05 -0000 >@@ -13,11 +13,12 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** > * >- * -exec-step-instruction >+ * -exec-step-instruction [--thread <tid>] [count] > > * Asynchronous command. Resumes the inferior which executes one > * machine instruction. The output, once GDB has stopped, will vary >@@ -29,10 +30,23 @@ > public class MIExecStepInstruction extends MICommand<MIInfo> > { > public MIExecStepInstruction(IExecutionDMContext dmc) { >- super(dmc, "-exec-step-instruction"); //$NON-NLS-1$ >+ this(dmc, 1); > } > > public MIExecStepInstruction(IExecutionDMContext dmc, int count) { > super(dmc, "-exec-step-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$ > } >+ >+ public MIExecStepInstruction(IMIExecutionDMContext dmc, boolean setThread) { >+ this(dmc, setThread, 1); >+ } >+ >+ public MIExecStepInstruction(IMIExecutionDMContext dmc, boolean setThread, int count) { >+ super(dmc, "-exec-step-instruction"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { Integer.toString(count) }); >+ } >+ } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecReturn.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java 22 Jul 2008 19:07:05 -0000 >@@ -17,7 +17,7 @@ > > /** > * >- * <code>-exec-return</code> >+ * -exec-return [args] > * > * <p> > * Makes current function return immediately. Doesn't execute the >@@ -38,5 +38,4 @@ > public MIExecReturn(IFrameDMContext dmc, String arg) { > super(dmc, "-exec-return", new String[] { arg }); //$NON-NLS-1$ > } >- > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecUntil.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java 22 Jul 2008 19:07:05 -0000 >@@ -14,11 +14,12 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** > * >- * -exec-until [ LOCATION ] >+ * -exec-until [--thread <tid>] [ LOCATION ] > * > * Asynchronous command. Executes the inferior until the LOCATION > * specified in the argument is reached. If there is no argument, the >@@ -34,6 +35,22 @@ > } > > public MIExecUntil(IExecutionDMContext dmc, String loc) { >- super(dmc, "-exec-until", new String[]{loc}); //$NON-NLS-1$ >+ super(dmc, "-exec-until", new String[] { loc }); //$NON-NLS-1$ >+ } >+ >+ public MIExecUntil(IMIExecutionDMContext dmc, boolean setThread) { >+ super(dmc, "-exec-until"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()) }); //$NON-NLS-1$ >+ } >+ } >+ >+ public MIExecUntil(IMIExecutionDMContext dmc, boolean setThread, String loc) { >+ super(dmc, "-exec-until"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), loc }); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { loc }); >+ } > } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStackListLocals.java >--- src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java 22 Jul 2008 19:07:05 -0000 >@@ -13,7 +13,9 @@ > > package org.eclipse.dd.mi.service.command.commands; > >+import org.eclipse.dd.dsf.datamodel.DMContexts; > import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIOutput; > import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo; > >@@ -30,12 +32,17 @@ > { > > public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) { >- super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$ >- if (printValues) { >- setParameters(new String[]{"1"}); //$NON-NLS-1$ >- } else { >- setParameters(new String[]{"0"}); //$NON-NLS-1$ >- } >+ this(frameCtx, false, printValues); >+ } >+ >+ public MIStackListLocals(IFrameDMContext frameCtx, boolean setThread, boolean printValues) { >+ super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$ >+ IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameCtx, IMIExecutionDMContext.class); >+ if (setThread && execDmc != null) { >+ setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), printValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ } else { >+ setParameters(new String[] { printValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ >+ } > } > > @Override >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecNext.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java 22 Jul 2008 19:07:05 -0000 >@@ -14,11 +14,12 @@ > package org.eclipse.dd.mi.service.command.commands; > > import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > > /** > * >- * -exec-next >+ * -exec-next [--thread <tid>] [count] > * > * Asynchronous command. Resumes execution of the inferior program, > * stopping when the beginning of the next source line is reached. >@@ -26,11 +27,24 @@ > */ > public class MIExecNext extends MICommand<MIInfo> > { >- public MIExecNext(IExecutionDMContext dmc) { >- super(dmc, "-exec-next"); //$NON-NLS-1$ >- } >+ public MIExecNext(IExecutionDMContext dmc) { >+ this(dmc, 1); >+ } > >- public MIExecNext(IExecutionDMContext dmc, int count) { >- super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$ >- } >-} >+ public MIExecNext(IExecutionDMContext dmc, int count) { >+ super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$ >+ } >+ >+ public MIExecNext(IMIExecutionDMContext dmc, boolean setThread) { >+ this(dmc, setThread, 1); >+ } >+ >+ public MIExecNext(IMIExecutionDMContext dmc, boolean setThread, int count) { >+ super(dmc, "-exec-next"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { Integer.toString(count) }); >+ } >+ } >+} >\ No newline at end of file >Index: src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStackInfoDepth.java >--- src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java 22 Jul 2008 19:07:05 -0000 >@@ -17,7 +17,7 @@ > > /** > * >- * -stack-info-depth [maxDepth] >+ * -stack-info-depth [--thread <tid>] [maxDepth] > * > * > */ >@@ -25,13 +25,30 @@ > { > > public MIStackInfoDepth(IMIExecutionDMContext ctx) { >+ this(ctx, false); >+ } >+ >+ public MIStackInfoDepth(IMIExecutionDMContext ctx, boolean setThread) { > super(ctx, "-stack-info-depth"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(ctx.getThreadId()) }); //$NON-NLS-1$ >+ } > } > > public MIStackInfoDepth(IMIExecutionDMContext ctx, int maxDepth) { >- super(ctx, "-stack-info-depth", new String[]{Integer.toString(maxDepth)}); //$NON-NLS-1$ >+ this(ctx, false, maxDepth); > } > >+ public MIStackInfoDepth(IMIExecutionDMContext ctx, boolean setThread, int maxDepth) { >+ super(ctx, "-stack-info-depth"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(ctx.getThreadId()), Integer.toString(maxDepth) }); //$NON-NLS-1$ >+ } >+ else { >+ setParameters(new String[] { Integer.toString(maxDepth) }); >+ } >+ } >+ > @Override > public MIStackInfoDepthInfo getResult(MIOutput out) { > return new MIStackInfoDepthInfo(out); >Index: src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStackSelectFrame.java >--- src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java 22 Jul 2008 19:07:05 -0000 >@@ -15,8 +15,6 @@ > import org.eclipse.dd.dsf.datamodel.IDMContext; > import org.eclipse.dd.mi.service.command.output.MIInfo; > >- >- > /** > * > * -stack-select-frame FRAMENUM >@@ -30,4 +28,8 @@ > public MIStackSelectFrame(IDMContext ctx, int frameNum) { > super(ctx, "-stack-select-frame", new String[]{Integer.toString(frameNum)}, new String[0]); //$NON-NLS-1$ > } >+ >+ public MIStackSelectFrame(IDMContext ctx, int threadNum, int frameNum) { >+ super(ctx, "-stack-select-frame", new String[]{ "--thread", Integer.toString(threadNum), Integer.toString(frameNum) }); //$NON-NLS-1$ //$NON-NLS-2$ >+ } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStackListArguments.java >--- src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java 22 Jul 2008 19:07:05 -0000 >@@ -20,7 +20,7 @@ > > /** > * >- * -stack-list-arguments SHOW-VALUES >+ * -stack-list-arguments [--thread <tid>] SHOW-VALUES > * [ LOW-FRAME HIGH-FRAME ] > * > * Display a list of the arguments for the frames between LOW-FRAME and >@@ -35,34 +35,35 @@ > public class MIStackListArguments extends MICommand<MIStackListArgumentsInfo> > { > public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues) { >+ this(execDmc, false, showValues); >+ } >+ >+ public MIStackListArguments(IMIExecutionDMContext execDmc, boolean setThread, boolean showValues) { > super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$ >- if (showValues) { >- setParameters(new String[]{"1"}); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), showValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ > } else { >- setParameters(new String[]{"0"}); //$NON-NLS-1$ >+ setParameters(new String[] { showValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ > } > } > > public MIStackListArguments(IFrameDMContext frameDmc, boolean showValues) { >- super(frameDmc, "-stack-list-arguments"); //$NON-NLS-1$ >- if (showValues) { >- setParameters(new String[]{"1"}); //$NON-NLS-1$ >- } else { >- setParameters(new String[]{"0"}); //$NON-NLS-1$ >- } >+ super(frameDmc, "-stack-list-arguments", new String[] { showValues ? "1" : "0" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ > } > > public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues, int low, int high) { >+ this(execDmc, false, showValues, low, high); >+ } >+ >+ public MIStackListArguments(IMIExecutionDMContext execDmc, boolean setThread, boolean showValues, int low, int high) { > super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$ >- String[] params = new String[3]; >- if (showValues) { >- params[0] = "1"; //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), //$NON-NLS-1$ >+ showValues ? "1" : "0", Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$ //$NON-NLS-2$ > } else { >- params[0] = "0"; //$NON-NLS-1$ >+ setParameters(new String[] { >+ showValues ? "1" : "0", Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$ //$NON-NLS-2$ > } >- params[1] = Integer.toString(low); >- params[2] = Integer.toString(high); >- setParameters(params); > } > > @Override >Index: src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java,v >retrieving revision 1.1 >diff -u -r1.1 MIExecContinue.java >--- src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java 22 Jul 2008 19:07:05 -0000 >@@ -17,7 +17,7 @@ > > /** > * >- * -exec-continue >+ * -exec-continue [--thread <tid>] > * > * Asynchronous command. Resumes the execution of the inferior program > * until a breakpoint is encountered, or until the inferior exits. >@@ -26,6 +26,17 @@ > public class MIExecContinue extends MICommand<MIInfo> > { > public MIExecContinue(IExecutionDMContext dmc) { >+ this(dmc, false); >+ } >+ >+ public MIExecContinue(IExecutionDMContext dmc, boolean allThreads) { > super(dmc, "-exec-continue"); //$NON-NLS-1$ >+ if (allThreads) { >+ setParameters(new String[] { "--all" }); //$NON-NLS-1$ >+ } >+ } >+ >+ public MIExecContinue(IExecutionDMContext dmc, int threadId) { >+ super(dmc, "-exec-continue", new String[] { "--thread", Integer.toString(threadId) }); //$NON-NLS-1$ //$NON-NLS-2$ > } > } >Index: src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java,v >retrieving revision 1.1 >diff -u -r1.1 MIStackListFrames.java >--- src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java 13 Feb 2008 20:34:28 -0000 1.1 >+++ src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java 22 Jul 2008 19:07:05 -0000 >@@ -54,12 +54,27 @@ > public class MIStackListFrames extends MICommand<MIStackListFramesInfo> > { > public MIStackListFrames(IMIExecutionDMContext execDmc) { >+ this(execDmc, false); >+ } >+ >+ public MIStackListFrames(IMIExecutionDMContext execDmc, boolean setThread) { > super(execDmc, "-stack-list-frames"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()) } ); //$NON-NLS-1$ >+ } > } > > public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) { >- super(execDmc, "-stack-list-frames", new String[]{Integer.toString(low), //$NON-NLS-1$ >- Integer.toString(high)}); >+ this(execDmc, false, low, high); >+ } >+ >+ public MIStackListFrames(IMIExecutionDMContext execDmc, boolean setThread, int low, int high) { >+ super(execDmc, "-stack-list-frames"); //$NON-NLS-1$ >+ if (setThread) { >+ setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$ >+ } else { >+ setParameters(new String[] { Integer.toString(low), Integer.toString(high) } ); >+ } > } > > @Override >Index: src/org/eclipse/dd/mi/service/MIBreakpointsManager.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIBreakpointsManager.java,v >retrieving revision 1.9 >diff -u -r1.9 MIBreakpointsManager.java >--- src/org/eclipse/dd/mi/service/MIBreakpointsManager.java 22 May 2008 20:04:22 -0000 1.9 >+++ src/org/eclipse/dd/mi/service/MIBreakpointsManager.java 22 Jul 2008 19:07:04 -0000 >@@ -71,7 +71,6 @@ > import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent; > import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent; > import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext; >-import org.eclipse.dd.mi.service.MIRunControl.MIExecutionDMC; > import org.eclipse.dd.mi.service.breakpoint.actions.BreakpointActionAdapter; > import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; > import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; >@@ -1516,8 +1515,8 @@ > Set<String> results = new HashSet<String>(); > if ((threads != null) && (supportsThreads(breakpoint))) { > for (IExecutionDMContext thread : threads) { >- if (thread instanceof MIExecutionDMC) { >- MIExecutionDMC dmc = (MIExecutionDMC) thread; >+ if (thread instanceof IMIExecutionDMContext) { >+ IMIExecutionDMContext dmc = (IMIExecutionDMContext) thread; > results.add(((Integer) dmc.getThreadId()).toString()); > } > } >Index: src/org/eclipse/dd/mi/service/MIMemory.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIMemory.java,v >retrieving revision 1.11 >diff -u -r1.11 MIMemory.java >--- src/org/eclipse/dd/mi/service/MIMemory.java 16 Jun 2008 18:27:01 -0000 1.11 >+++ src/org/eclipse/dd/mi/service/MIMemory.java 22 Jul 2008 19:07:04 -0000 >@@ -69,8 +69,6 @@ > } > } > >- @SuppressWarnings("unused") >- private MIRunControl fRunControl; > private MIMemoryCache fMemoryCache; > > /** >@@ -113,9 +111,6 @@ > // Register this service > register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>()); > >- // Get the RunControl so we can retrieve the current Execution context >- fRunControl = getServicesTracker().getService(MIRunControl.class); >- > // Create the memory requests cache > fMemoryCache = new MIMemoryCache(); > >@@ -279,7 +274,7 @@ > ////////////////////////////////////////////////////////////////////////// > > @DsfServiceEventHandler >- public void eventDispatched(IRunControl.IResumedDMEvent e) { >+ public void eventDispatched(IRunControl.IContainerResumedDMEvent e) { > fMemoryCache.setTargetAvailable(e.getDMContext(), false); > if (e.getReason() != StateChangeReason.STEP) { > fMemoryCache.reset(); >@@ -287,7 +282,7 @@ > } > > @DsfServiceEventHandler >- public void eventDispatched(IRunControl.ISuspendedDMEvent e) { >+ public void eventDispatched(IRunControl.IContainerSuspendedDMEvent e) { > fMemoryCache.setTargetAvailable(e.getDMContext(), true); > fMemoryCache.reset(); > } >Index: src/org/eclipse/dd/mi/service/ExpressionService.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java,v >retrieving revision 1.11 >diff -u -r1.11 ExpressionService.java >--- src/org/eclipse/dd/mi/service/ExpressionService.java 16 Jul 2008 19:46:15 -0000 1.11 >+++ src/org/eclipse/dd/mi/service/ExpressionService.java 22 Jul 2008 19:07:03 -0000 >@@ -893,7 +893,6 @@ > } > } > >- > @DsfServiceEventHandler > public void eventDispatched(IRunControl.IResumedDMEvent e) { > fExpressionCache.setContextAvailable(e.getDMContext(), false); >Index: src/org/eclipse/dd/mi/service/MIRunControl.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java,v >retrieving revision 1.15 >diff -u -r1.15 MIRunControl.java >--- src/org/eclipse/dd/mi/service/MIRunControl.java 10 Jul 2008 13:18:26 -0000 1.15 >+++ src/org/eclipse/dd/mi/service/MIRunControl.java 22 Jul 2008 19:07:05 -0000 >@@ -21,7 +21,6 @@ > 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; >@@ -71,197 +70,212 @@ > * events and track service state, to be perfectly in sync with the service > * state. > */ >-public class MIRunControl extends AbstractDsfService implements IRunControl >+public class MIRunControl extends AbstractDsfService implements IMIRunControl > { >- protected class MIExecutionDMC extends AbstractDMContext >- implements IMIExecutionDMContext >- { >- /** >- * Integer ID that is used to identify the thread in the GDB/MI protocol. >- */ >- private final int fThreadId; >- >- /** >- * Constructor for the context. It should not be called directly by clients. >- * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)} >- * to create instances of this context based on the thread ID. >- * <p/> >- * Classes extending {@link MIRunControl} may also extend this class to include >- * additional information in the context. >- * >- * @param sessionId Session that this context belongs to. >- * @param containerDmc The container that this context belongs to. >- * @param threadId GDB/MI thread identifier. >- */ >- protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) { >- super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]); >- fThreadId = threadId; >- } >- >- /** >- * Returns the GDB/MI thread identifier of this context. >- * @return >- */ >- public int getThreadId(){ >- return fThreadId; >- } >- >- @Override >- public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ >- >- @Override >- public boolean equals(Object obj) { >- return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId; >- } >- >- @Override >- public int hashCode() { return super.baseHashCode() ^ fThreadId; } >- } >- >- @Immutable >- private static class ExecutionData implements IExecutionDMData { >- private final StateChangeReason fReason; >- ExecutionData(StateChangeReason reason) { >- fReason = reason; >- } >- public StateChangeReason getStateChangeReason() { return fReason; } >- } >+ class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext >+ { >+ /** >+ * Integer ID that is used to identify the thread in the GDB/MI protocol. >+ */ >+ private final int fThreadId; >+ >+ /** >+ * Constructor for the context. It should not be called directly by clients. >+ * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)} >+ * to create instances of this context based on the thread ID. >+ * <p/> >+ * Classes extending {@link MIRunControl} may also extend this class to include >+ * additional information in the context. >+ * >+ * @param sessionId Session that this context belongs to. >+ * @param containerDmc The container that this context belongs to. >+ * @param threadId GDB/MI thread identifier. >+ */ >+ protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) { >+ super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]); >+ fThreadId = threadId; >+ } > >- /** >- * Base class for events generated by the MI Run Control service. Most events >- * generated by the MI Run Control service are directly caused by some MI event. >- * Other services may need access to the extended MI data carried in the event. >- * >- * @param <V> DMC that this event refers to >- * @param <T> MIInfo object that is the direct cause of this event >- * @see MIRunControl >- */ >- @Immutable >- protected static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V> >- implements IDMEvent<V>, IMIDMEvent >- { >- final private T fMIInfo; >- public RunControlEvent(V dmc, T miInfo) { >- super(dmc); >- fMIInfo = miInfo; >- } >- >- public T getMIEvent() { return fMIInfo; } >- } >- >- /** >- * Indicates that the given thread has been suspended. >- */ >- @Immutable >- protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent> >- implements ISuspendedDMEvent >- { >- SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) { >- super(ctx, miInfo); >- } >- >- public StateChangeReason getReason() { >- if (getMIEvent() instanceof MIBreakpointHitEvent) { >- return StateChangeReason.BREAKPOINT; >- } else if (getMIEvent() instanceof MISteppingRangeEvent) { >- return StateChangeReason.STEP; >- } else if (getMIEvent() instanceof MISharedLibEvent) { >- return StateChangeReason.SHAREDLIB; >- }else if (getMIEvent() instanceof MISignalEvent) { >- return StateChangeReason.SIGNAL; >- }else if (getMIEvent() instanceof MIWatchpointTriggerEvent) { >- return StateChangeReason.WATCHPOINT; >- }else if (getMIEvent() instanceof MIErrorEvent) { >- return StateChangeReason.ERROR; >- }else { >- return StateChangeReason.USER_REQUEST; >- } >- } >- } >+ /** >+ * Returns the GDB/MI thread identifier of this context. >+ * @return >+ */ >+ public int getThreadId(){ >+ return fThreadId; >+ } > >- @Immutable >- protected static class ContainerSuspendedEvent extends SuspendedEvent >- implements IContainerSuspendedDMEvent >- { >- final IExecutionDMContext[] triggeringDmcs; >- ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { >- super(containerDmc, miInfo); >- this.triggeringDmcs = triggeringDmc != null >- ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >- } >- >- public IExecutionDMContext[] getTriggeringContexts() { >- return triggeringDmcs; >- } >- } >+ @Override >+ public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ > >- @Immutable >- protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent> >- implements IResumedDMEvent >- { >- ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) { >- super(ctx, miInfo); >- } >- >- public StateChangeReason getReason() { >- switch(getMIEvent().getType()) { >- case MIRunningEvent.CONTINUE: >- return StateChangeReason.USER_REQUEST; >- case MIRunningEvent.NEXT: >- case MIRunningEvent.NEXTI: >- return StateChangeReason.STEP; >- case MIRunningEvent.STEP: >- case MIRunningEvent.STEPI: >- return StateChangeReason.STEP; >- case MIRunningEvent.FINISH: >- return StateChangeReason.STEP; >- case MIRunningEvent.UNTIL: >- case MIRunningEvent.RETURN: >- break; >- } >- return StateChangeReason.UNKNOWN; >- } >- } >+ @Override >+ public boolean equals(Object obj) { >+ return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId; >+ } > >- @Immutable >- protected static class ContainerResumedEvent extends ResumedEvent >- implements IContainerResumedDMEvent >- { >- final IExecutionDMContext[] triggeringDmcs; >- >- ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { >- super(containerDmc, miInfo); >- this.triggeringDmcs = triggeringDmc != null >- ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >- } >- >- public IExecutionDMContext[] getTriggeringContexts() { >- return triggeringDmcs; >- } >- } >- >- @Immutable >- protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent> >- implements IStartedDMEvent >- { >- StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { >- super(executionDmc, miInfo); >- } >- } >- >- @Immutable >- protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent> >- implements IExitedDMEvent >- { >- ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { >- super(executionDmc, miInfo); >- } >- } >- >- private AbstractMIControl fConnection; >+ @Override >+ public int hashCode() { return super.baseHashCode() ^ fThreadId; } >+ } >+ >+ @Immutable >+ static class ExecutionData implements IExecutionDMData { >+ private final StateChangeReason fReason; >+ ExecutionData(StateChangeReason reason) { >+ fReason = reason; >+ } >+ public StateChangeReason getStateChangeReason() { return fReason; } >+ } >+ >+ /** >+ * Base class for events generated by the MI Run Control service. Most events >+ * generated by the MI Run Control service are directly caused by some MI event. >+ * Other services may need access to the extended MI data carried in the event. >+ * >+ * @param <V> DMC that this event refers to >+ * @param <T> MIInfo object that is the direct cause of this event >+ * @see MIRunControl >+ */ >+ @Immutable >+ static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V> >+ implements IDMEvent<V>, IMIDMEvent >+ { >+ final private T fMIInfo; >+ public RunControlEvent(V dmc, T miInfo) { >+ super(dmc); >+ fMIInfo = miInfo; >+ } >+ >+ public T getMIEvent() { return fMIInfo; } >+ } >+ >+ /** >+ * Indicates that the given thread has been suspended. >+ */ >+ @Immutable >+ static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent> >+ implements ISuspendedDMEvent >+ { >+ SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) { >+ super(ctx, miInfo); >+ } >+ >+ public StateChangeReason getReason() { >+ if (getMIEvent() instanceof MIBreakpointHitEvent) { >+ return StateChangeReason.BREAKPOINT; >+ } else if (getMIEvent() instanceof MISteppingRangeEvent) { >+ return StateChangeReason.STEP; >+ } else if (getMIEvent() instanceof MISharedLibEvent) { >+ return StateChangeReason.SHAREDLIB; >+ }else if (getMIEvent() instanceof MISignalEvent) { >+ return StateChangeReason.SIGNAL; >+ }else if (getMIEvent() instanceof MIWatchpointTriggerEvent) { >+ return StateChangeReason.WATCHPOINT; >+ }else if (getMIEvent() instanceof MIErrorEvent) { >+ return StateChangeReason.ERROR; >+ }else { >+ return StateChangeReason.USER_REQUEST; >+ } >+ } >+ } >+ >+ @Immutable >+ static class ContainerSuspendedEvent extends SuspendedEvent >+ implements IContainerSuspendedDMEvent >+ { >+ final IExecutionDMContext[] triggeringDmcs; >+ ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { >+ super(containerDmc, miInfo); >+ this.triggeringDmcs = triggeringDmc != null >+ ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >+ } >+ >+ public IExecutionDMContext[] getTriggeringContexts() { >+ return triggeringDmcs; >+ } >+ } >+ >+ @Immutable >+ static class ThreadSuspendedEvent extends SuspendedEvent >+ { >+ ThreadSuspendedEvent(IExecutionDMContext executionDmc, MIStoppedEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent> >+ implements IResumedDMEvent >+ { >+ ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) { >+ super(ctx, miInfo); >+ } >+ >+ public StateChangeReason getReason() { >+ switch(getMIEvent().getType()) { >+ case MIRunningEvent.CONTINUE: >+ return StateChangeReason.USER_REQUEST; >+ case MIRunningEvent.NEXT: >+ case MIRunningEvent.NEXTI: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.STEP: >+ case MIRunningEvent.STEPI: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.FINISH: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.UNTIL: >+ case MIRunningEvent.RETURN: >+ break; >+ } >+ return StateChangeReason.UNKNOWN; >+ } >+ } >+ >+ @Immutable >+ static class ContainerResumedEvent extends ResumedEvent >+ implements IContainerResumedDMEvent >+ { >+ final IExecutionDMContext[] triggeringDmcs; >+ >+ ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { >+ super(containerDmc, miInfo); >+ this.triggeringDmcs = triggeringDmc != null >+ ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >+ } >+ >+ public IExecutionDMContext[] getTriggeringContexts() { >+ return triggeringDmcs; >+ } >+ } >+ >+ @Immutable >+ static class ThreadResumedEvent extends ResumedEvent >+ { >+ ThreadResumedEvent(IExecutionDMContext executionDmc, MIRunningEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent> >+ implements IStartedDMEvent >+ { >+ StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent> >+ implements IExitedDMEvent >+ { >+ ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ private AbstractMIControl fConnection; > private CommandCache fMICommandCache; > >- // state flags >+ // State flags > private boolean fSuspended = true; > private boolean fResumePending = false; > private boolean fStepping = false; >@@ -291,9 +305,6 @@ > fMICommandCache = new CommandCache(getSession(), fConnection); > fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true); > getSession().addServiceEventListener(this, null); >- >- //register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>()); >- > rm.done(); > } > >Index: src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java,v >retrieving revision 1.4 >diff -u -r1.4 CLIEventProcessor.java >--- src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java 15 May 2008 02:41:54 -0000 1.4 >+++ src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java 22 Jul 2008 19:07:05 -0000 >@@ -57,7 +57,6 @@ > // Last Thread ID created > private static int fLastThreadId; > >- > public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) { > fCommandControl = connection; > fInferior = inferior; >@@ -109,32 +108,16 @@ > fEventList.add(oobr); > > if (oobr instanceof MIConsoleStreamOutput) { >- // Process Events of type DsfMIConsoleStreamOutput here >- MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr; >+ // Process Events of type DsfMIConsoleStreamOutput here >+ MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr; > >- // Look for events with Pattern ^[New Thread 1077300144 (LWP 7973) >- Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$ >- Matcher matcher = pattern.matcher(exec.getCString()); >- if (matcher.find()) { >- //fMapThreadIds.put(matcher.group(2), Integer.valueOf(++fLastThreadId)); >- //DsfMIEvent e = new DsfMIThreadCreatedEvent(Integer.valueOf(matcher.group(2))); >- MIEvent<?> e = new MIThreadCreatedEvent(fContainerDmc, ++fLastThreadId); >- // Dispatch DsfMIThreadCreatedEvent >- fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties()); >- } >- // HACK - 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. >- // Look for Thread Exited Event with Pattern [Thread 1077300144 (LWP 23832) exited]\n >- // See bug 200615 for details. >-// pattern = Pattern.compile("(^\\[Thread.*LWP\\s)(\\d*)(.*exited.*$)", Pattern.MULTILINE); //$NON-NLS-1$ >-// matcher = pattern.matcher(exec.getCString()); >-// if (matcher.find()) { >-// DsfMIEvent e = new DsfMIThreadExitEvent(fMapThreadIds.get(matcher.group(2)).intValue()); >-// // Dispatch DsfMIThreadExitEvent >-// fConnection.getSession().dispatchEvent(e, fConnection.getProperties()); >-// } >+ // Look for events with Pattern ^[New Thread 1077300144 (LWP 7973) >+ 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); >+ fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties()); >+ } > } > } > >Index: src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java,v >retrieving revision 1.4 >diff -u -r1.4 MIRunControlEventProcessor.java >--- src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java 2 Jun 2008 18:27:34 -0000 1.4 >+++ src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java 22 Jul 2008 19:07:05 -0000 >@@ -22,7 +22,8 @@ > 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.MIRunControl; >+import org.eclipse.dd.mi.service.IMIExecutionDMContext; >+import org.eclipse.dd.mi.service.IMIRunControl; > 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; >@@ -41,6 +42,8 @@ > import org.eclipse.dd.mi.service.command.events.MISignalEvent; > import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent; > import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; >+import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent; >+import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent; > import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent; > import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; > import org.eclipse.dd.mi.service.command.output.MIConst; >@@ -51,7 +54,6 @@ > import org.eclipse.dd.mi.service.command.output.MIOutput; > import org.eclipse.dd.mi.service.command.output.MIResult; > import org.eclipse.dd.mi.service.command.output.MIResultRecord; >-import org.eclipse.dd.mi.service.command.output.MIStatusAsyncOutput; > import org.eclipse.dd.mi.service.command.output.MIValue; > > /** >@@ -102,57 +104,95 @@ > } > > public void eventReceived(Object output) { >- for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { >- if (oobr instanceof MIExecAsyncOutput) { >- MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr; >- // Change of state. >- String state = exec.getAsyncClass(); >- if ("stopped".equals(state)) { //$NON-NLS-1$ >- // Re-set the thread and stack level to -1 when stopped event is recvd. >- // This is to synchronize the state between GDB back-end and AbstractMIControl. >- fCommandControl.resetCurrentThreadLevel(); >- fCommandControl.resetCurrentStackLevel(); >- >- List<MIEvent<?>> events = new LinkedList<MIEvent<?>>(); >- 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; >- } >- } >- } >- } >- >- // 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(MIRunControl.class), fContainerDmc, exec.getToken(), exec.getMIResults()); >- events.add(e); >- } >- for (MIEvent<?> event : events) { >- fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); >- } >- } >- } >- else if (oobr instanceof MIStatusAsyncOutput) { >- // Nothing done .. but what about +download?? >- } else if (oobr instanceof MINotifyAsyncOutput) { >- // Nothing >- } >- } >+ for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { >+ List<MIEvent<?>> events = new LinkedList<MIEvent<?>>(); >+ if (oobr instanceof MIExecAsyncOutput) { >+ MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr; >+ // Change of state. >+ String state = exec.getAsyncClass(); >+ if ("stopped".equals(state)) { //$NON-NLS-1$ >+ // Re-set the thread and stack level to -1 when stopped event is recvd. >+ // This is to synchronize the state between GDB back-end and AbstractMIControl. >+ fCommandControl.resetCurrentThreadLevel(); >+ fCommandControl.resetCurrentStackLevel(); >+ >+ 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; >+ } >+ } >+ } >+ } >+ // 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()); >+ } >+ } >+ else if ("running".equals(state)) { //$NON-NLS-1$ >+ int token = exec.getToken(); >+ 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()); >+ } >+ } >+ } >+ } >+ >+ } >+ 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()); >+ } >+ } >+ else if ("thread-exited".equals(miEvent)) { //$NON-NLS-1$ >+ MIEvent<?> event = MIThreadExitEvent.parse(fContainerDmc, exec.getToken(), exec.getMIResults()); >+ if (event != null) { >+ fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties()); >+ } >+ } >+ } >+ } > } > > protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) { >- MIRunControl runControl = fServicesTracker.getService(MIRunControl.class); >+ IMIRunControl runControl = fServicesTracker.getService(IMIRunControl.class); > MIEvent<?> event = null; > if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$ > event = MIBreakpointHitEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults()); >@@ -213,7 +253,7 @@ > else if (cmd instanceof MIExecFinish) { type = MIRunningEvent.FINISH; } > else if (cmd instanceof MIExecReturn) { type = MIRunningEvent.RETURN; } > else if (cmd instanceof MIExecContinue) { type = MIRunningEvent.CONTINUE; } >- else { type = MIRunningEvent.CONTINUE; } >+ else { type = MIRunningEvent.CONTINUE; } > > fCommandControl.getSession().dispatchEvent( > new MIRunningEvent(fContainerDmc, id, type), fCommandControl.getProperties()); >Index: src/org/eclipse/dd/mi/service/command/AbstractMIControl.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java,v >retrieving revision 1.14 >diff -u -r1.14 AbstractMIControl.java >--- src/org/eclipse/dd/mi/service/command/AbstractMIControl.java 2 Jun 2008 18:27:34 -0000 1.14 >+++ src/org/eclipse/dd/mi/service/command/AbstractMIControl.java 22 Jul 2008 19:07:05 -0000 >@@ -31,6 +31,8 @@ > import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; > import org.eclipse.dd.dsf.concurrent.DsfRunnable; > import org.eclipse.dd.dsf.datamodel.DMContexts; >+import org.eclipse.dd.dsf.datamodel.IDMContext; >+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.ICommand; > import org.eclipse.dd.dsf.debug.service.command.ICommandControl; >@@ -74,7 +76,7 @@ > private RxThread fRxThread; > > private int fCurrentStackLevel = -1; >- private int fCurrentThreadId = -1; >+ private int fCurrentThreadId = -1; > > > private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>(); >@@ -85,7 +87,6 @@ > * that the TX thread should shut down. > */ > private final CommandHandle fTerminatorHandle = new CommandHandle(null, null); >- > > /* > * Various listener control variables used to keep track of listeners who want to monitor >@@ -207,7 +208,7 @@ > // Cast the return token to match the result type of MI Command. This is checking > // against an erased type so it should never throw any exceptions. > @SuppressWarnings("unchecked") >- DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>)rm; >+ DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>) rm; > > final CommandHandle handle = new CommandHandle(miCommand, miDone); > >@@ -240,38 +241,43 @@ > } > > private void processNextQueuedCommand() { >- if ( fCommandQueue.size() > 0 ) { >- CommandHandle handle = fCommandQueue.remove(0); >- if ( handle != null ) { >+ if (fCommandQueue.size() > 0) { >+ final CommandHandle handle = fCommandQueue.remove(0); >+ if (handle != null) { > processCommandSent(handle); > >- // Before the command is sent, Check the Thread Id and send it to >- // the queue only if the id has been changed. >- if( handle.getThreadId()!= null && >- handle.getThreadId().intValue() != fCurrentThreadId && handle.getThreadId().intValue() != 0) >- { >- // Re-set the level >- fCurrentThreadId = handle.getThreadId().intValue(); >- CommandHandle cmdHandle = new CommandHandle( >- new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); >- cmdHandle.generateTokenId(); >- fTxCommands.add(cmdHandle); >- } >- >- // Before the command is sent, Check the Stack level and send it to >- // the queue only if the level has been changed. >- if( handle.getStackFrameId()!= null && >- handle.getStackFrameId().intValue() != fCurrentStackLevel) >- { >- // Re-set the level >- fCurrentStackLevel = handle.getStackFrameId().intValue(); >- CommandHandle cmdHandle = new CommandHandle( >- new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); >- cmdHandle.generateTokenId(); >- fTxCommands.add(cmdHandle); >+ // Identify target thread/frame (we might have to update them at the target) >+ final IDMContext targetContext = handle.fCommand.getContext(); >+ final int targetThread = (handle.getThreadId() != null) ? handle.getThreadId().intValue() : -1; >+ final int targetFrame = (handle.getStackFrameId() != null) ? handle.getStackFrameId().intValue() : -1; >+ >+ // The thread-select and frame-select make sense only if the thread is stopped. >+ // Some non-stop commands don't require the thread to be stopped so we send the >+ // command anyway. >+ IRunControl runControl = getServicesTracker().getService(IRunControl.class); >+ IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(targetContext, IMIExecutionDMContext.class); >+ if (runControl != null && execDmc != null && runControl.isSuspended(execDmc)) { >+ // Before the command is sent, Check the Thread Id and send it to >+ // the queue only if the id has been changed. >+ if (targetThread != -1 && targetThread != fCurrentThreadId) { >+ fCurrentThreadId = targetThread; >+ resetCurrentStackLevel(); >+ CommandHandle cmdHandle = new CommandHandle(new MIThreadSelect(execDmc), null); >+ cmdHandle.generateTokenId(); >+ fTxCommands.add(cmdHandle); >+ } >+ >+ // Before the command is sent, Check the Stack level and send it to >+ // the queue only if the level has been changed. >+ if (targetFrame != -1 && targetFrame != fCurrentStackLevel) { >+ fCurrentStackLevel = targetFrame; >+ CommandHandle cmdHandle = new CommandHandle(new MIStackSelectFrame(execDmc, targetFrame), null); >+ cmdHandle.generateTokenId(); >+ fTxCommands.add(cmdHandle); >+ } > } >- handle.generateTokenId(); >- fTxCommands.add(handle); >+ handle.generateTokenId(); >+ fTxCommands.add(handle); > } > } > } >Index: src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java,v >retrieving revision 1.2 >diff -u -r1.2 CLIInfoThreadsInfo.java >--- src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java 11 Jun 2008 18:12:28 -0000 1.2 >+++ src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java 22 Jul 2008 19:07:06 -0000 >@@ -35,7 +35,7 @@ > parse(); > } > >- public class ThreadInfo{ >+ public class ThreadInfo { > String fName; > String fGdbId; > String fPid; >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.dd.dsf/plugins/org.eclipse.dd.mi/META-INF/MANIFEST.MF,v >retrieving revision 1.3 >diff -u -r1.3 MANIFEST.MF >--- META-INF/MANIFEST.MF 1 Jul 2008 18:03:47 -0000 1.3 >+++ META-INF/MANIFEST.MF 22 Jul 2008 19:07:03 -0000 >@@ -13,6 +13,7 @@ > org.eclipse.cdt.debug.core, > org.eclipse.cdt.core > Export-Package: >+ org.eclipse.dd.mi.internal, > org.eclipse.dd.mi.service, > org.eclipse.dd.mi.service.command, > org.eclipse.dd.mi.service.command.commands, >Index: src/org/eclipse/dd/mi/service/IMIRunControl.java >=================================================================== >RCS file: src/org/eclipse/dd/mi/service/IMIRunControl.java >diff -N src/org/eclipse/dd/mi/service/IMIRunControl.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/mi/service/IMIRunControl.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,27 @@ >+/******************************************************************************* >+ * 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.mi.service; >+ >+import org.eclipse.dd.dsf.debug.service.IRunControl; >+ >+/** >+ * 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 IMIRunControl extends IRunControl >+{ >+ public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId); >+} >Index: src/org/eclipse/dd/mi/service/MIStackNS.java >=================================================================== >RCS file: src/org/eclipse/dd/mi/service/MIStackNS.java >diff -N src/org/eclipse/dd/mi/service/MIStackNS.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/mi/service/MIStackNS.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,677 @@ >+/******************************************************************************* >+ * 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 handling of multiple execution contexts >+ *******************************************************************************/ >+package org.eclipse.dd.mi.service; >+ >+import java.util.ArrayList; >+import java.util.Arrays; >+import java.util.Hashtable; >+import java.util.List; >+ >+import org.eclipse.cdt.core.IAddress; >+import org.eclipse.cdt.utils.Addr32; >+import org.eclipse.cdt.utils.Addr64; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; >+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; >+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.IStack; >+import org.eclipse.dd.dsf.debug.service.IStack2; >+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; >+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.commands.MIStackInfoDepth; >+import org.eclipse.dd.mi.service.command.commands.MIStackListArguments; >+import org.eclipse.dd.mi.service.command.commands.MIStackListFrames; >+import org.eclipse.dd.mi.service.command.commands.MIStackListLocals; >+import org.eclipse.dd.mi.service.command.events.IMIDMEvent; >+import org.eclipse.dd.mi.service.command.events.MIEvent; >+import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; >+import org.eclipse.dd.mi.service.command.output.MIArg; >+import org.eclipse.dd.mi.service.command.output.MIFrame; >+import org.eclipse.dd.mi.service.command.output.MIStackInfoDepthInfo; >+import org.eclipse.dd.mi.service.command.output.MIStackListArgumentsInfo; >+import org.eclipse.dd.mi.service.command.output.MIStackListFramesInfo; >+import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo; >+import org.osgi.framework.BundleContext; >+ >+public class MIStackNS extends AbstractDsfService >+ implements IStack2 >+{ >+ protected static class MIFrameDMC extends AbstractDMContext >+ implements IFrameDMContext >+ { >+ private final int fLevel; >+ // public MIFrameDMC(MIStack service, int level) { >+ public MIFrameDMC(String sessionId, IExecutionDMContext execDmc, int level) { >+ super(sessionId, new IDMContext[] { execDmc }); >+ fLevel = level; >+ } >+ >+ public int getLevel() { return fLevel; } >+ >+ @Override >+ public boolean equals(Object other) { >+ return super.baseEquals(other) && ((MIFrameDMC)other).fLevel == fLevel; >+ } >+ >+ @Override >+ public int hashCode() { >+ return super.baseHashCode() ^ fLevel; >+ } >+ >+ @Override >+ public String toString() { >+ return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ } >+ >+ protected static class MIVariableDMC extends AbstractDMContext >+ implements IVariableDMContext >+ { >+ public enum Type { ARGUMENT, LOCAL } >+ final private Type fType; >+ final private int fIndex; >+ >+ public MIVariableDMC(MIStackNS service, IFrameDMContext frame, Type type, int index) { >+ super(service, new IDMContext[] { frame }); >+ fIndex = index; >+ fType = type; >+ } >+ >+ public int getIndex() { return fIndex; } >+ public Type getType() { return fType; } >+ >+ @Override >+ public boolean equals(Object other) { >+ return super.baseEquals(other) && >+ ((MIVariableDMC)other).fType == fType && >+ ((MIVariableDMC)other).fIndex == fIndex; >+ } >+ >+ @Override >+ public int hashCode() { >+ int typeFactor = 0; >+ if (fType == Type.LOCAL) typeFactor = 2; >+ else if (fType == Type.ARGUMENT) typeFactor = 3; >+ return super.baseHashCode() ^ typeFactor ^ fIndex; >+ } >+ >+ @Override >+ public String toString() { >+ return baseToString() + ".variable(" + fType + ")[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ } >+ } >+ >+ private CommandCache fMICommandCache; >+ private MIStoppedEvent fCachedStoppedEvent; >+ private IMIRunControl fMIRunControl; >+ >+ public MIStackNS(DsfSession session) >+ { >+ super(session); >+ } >+ >+ @Override >+ protected BundleContext getBundleContext() >+ { >+ return MIPlugin.getBundleContext(); >+ } >+ >+ @Override >+ public void initialize(final RequestMonitor rm) { >+ super.initialize( >+ new RequestMonitor(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ doInitialize(rm); >+ } >+ }); >+ } >+ >+ private void doInitialize(RequestMonitor rm) { >+ AbstractMIControl miControl = getServicesTracker().getService(AbstractMIControl.class); >+ fMICommandCache = new CommandCache(getSession(), miControl); >+ fMICommandCache.setContextAvailable(miControl.getControlDMContext(), true); >+ fMIRunControl = getServicesTracker().getService(IMIRunControl.class); >+ >+ getSession().addServiceEventListener(this, null); >+ register(new String[]{IStack.class.getName(), MIStackNS.class.getName()}, new Hashtable<String,String>()); >+ rm.done(); >+ } >+ >+ @Override >+ public void shutdown(RequestMonitor rm) >+ { >+ unregister(); >+ getSession().removeServiceEventListener(this); >+ fMICommandCache.reset(); >+ super.shutdown(rm); >+ } >+ >+ @SuppressWarnings("unchecked") >+ public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) { >+ if (dmc instanceof MIFrameDMC) { >+ getFrameData((MIFrameDMC)dmc, (DataRequestMonitor<IFrameDMData>)rm); >+ // getFrameData invokes rm >+ } else if (dmc instanceof MIVariableDMC) { >+ getVariableData((MIVariableDMC)dmc, (DataRequestMonitor<IVariableDMData>)rm); >+ // getVariablesData invokes rm >+ } else { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ } >+ >+ /** >+ * Creates a frame context. This method is intended to be used by other MI >+ * services and sub-classes which need to create a frame context directly. >+ * <p> >+ * Sub-classes can override this method to provide custom stack frame >+ * context implementation. >+ * </p> >+ * @param execDmc Execution context that this frame is to be a child of. >+ * @param level Level of the new context. >+ * @return A new frame context. >+ */ >+ public IFrameDMContext createFrameDMContext(IExecutionDMContext execDmc, int level) { >+ return new MIFrameDMC(getSession().getId(), execDmc, level); >+ } >+ >+ public void getFrames(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext[]> rm) { >+ getFrames(ctx, 0, ALL_FRAMES, rm); >+ } >+ >+ public void getFrames(final IDMContext ctx, final int startIndex, final int endIndex, final DataRequestMonitor<IFrameDMContext[]> rm) { >+ >+ // Make sure we have an execution context (ideally a thread) >+ final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context " + ctx, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Make sure the indices are OK >+ if (startIndex < 0 || endIndex > 0 && endIndex < startIndex) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid stack frame range [" + startIndex + ',' + endIndex + ']', null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Make sure the thread is stopped >+ if (!fMIRunControl.isSuspended(execDmc)) { >+ rm.setData(new IFrameDMContext[0]); >+ rm.done(); >+ return; >+ } >+ >+ // Case of retrieving the top stack frame from the cached stopped event. >+ if (startIndex == 0 && endIndex == 0) { >+ if (fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null && >+ execDmc.equals(fCachedStoppedEvent.getDMContext())) >+ { >+ rm.setData(new IFrameDMContext[] { createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel()) }); >+ rm.done(); >+ return; >+ } >+ } >+ >+ // Select the proper MI command variant >+ final MIStackListFrames miStackListCmd; >+ final int firstIndex; >+ if (endIndex >= 0) { >+ miStackListCmd = new MIStackListFrames(execDmc, true, startIndex, endIndex); >+ firstIndex = startIndex; >+ } else { >+ miStackListCmd = new MIStackListFrames(execDmc, true); >+ firstIndex = 0; >+ } >+ >+ // And go... >+ fMICommandCache.execute( >+ miStackListCmd, >+ new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ rm.setData(getFrames(execDmc, getData(), firstIndex, endIndex, startIndex)); >+ rm.done(); >+ } >+ }); >+ } >+ >+ public void getTopFrame(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext> rm) { >+ final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Try to retrieve the top stack frame from the cached stopped event. >+ if (fCachedStoppedEvent != null && >+ fCachedStoppedEvent.getFrame() != null && >+ execDmc.equals(fCachedStoppedEvent.getDMContext())) >+ { >+ rm.setData(createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel())); >+ rm.done(); >+ return; >+ } >+ >+ // If stopped event is not available or doesn't contain frame info, >+ // query top stack frame >+ getFrames( >+ ctx, >+ 0, >+ 0, >+ new DataRequestMonitor<IFrameDMContext[]>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ rm.setData(getData()[0]); >+ rm.done(); >+ } >+ }); >+ } >+ >+ //private MIFrameDMC[] getFrames(DsfMIStackListFramesInfo info) { >+ private IFrameDMContext[] getFrames(IMIExecutionDMContext execDmc, MIStackListFramesInfo info, int firstIndex, int lastIndex, int startIndex) { >+ int length = info.getMIFrames().length; >+ if (lastIndex > 0) { >+ int limit= lastIndex - startIndex + 1; >+ if (limit < length) { >+ length = limit; >+ } >+ } >+ IFrameDMContext[] frameDMCs = new MIFrameDMC[length]; >+ for (int i = 0; i < length; i++) { >+ //frameDMCs[i] = new MIFrameDMC(this, info.getMIFrames()[i].getLevel()); >+ final MIFrame frame= info.getMIFrames()[i + startIndex - firstIndex]; >+ assert startIndex + i == frame.getLevel(); >+ frameDMCs[i] = createFrameDMContext(execDmc, frame.getLevel()); >+ } >+ return frameDMCs; >+ } >+ >+ >+ >+ public void getFrameData(final IFrameDMContext frameDmc, final DataRequestMonitor<IFrameDMData> rm) { >+ if (!(frameDmc instanceof MIFrameDMC)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ final MIFrameDMC miFrameDmc = (MIFrameDMC)frameDmc; >+ >+ IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ /** >+ * Base class for the IFrameDMData object that uses an MIFrame object to >+ * provide the data. Sub-classes must provide the MIFrame object >+ */ >+ abstract class FrameData implements IFrameDMData >+ { >+ abstract protected MIFrame getMIFrame(); >+ >+ public IAddress getAddress() { >+ String addr = getMIFrame().getAddress(); >+ if (addr.startsWith("0x")) { //$NON-NLS-1$ >+ addr = addr.substring(2); >+ } >+ if (addr.length() <= 8) { >+ return new Addr32(getMIFrame().getAddress()); >+ } else { >+ return new Addr64(getMIFrame().getAddress()); >+ } >+ } >+ >+ public int getColumn() { return 0; } >+ >+ public String getFile() { return getMIFrame().getFile(); } >+ public int getLine() { return getMIFrame().getLine(); } >+ public String getFunction() { return getMIFrame().getFunction(); } >+ >+ @Override >+ public String toString() { return getMIFrame().toString(); } >+ } >+ >+ // If requested frame is the top stack frame, try to retrieve it from >+ // the stopped event data. >+ class FrameDataFromStoppedEvent extends FrameData { >+ private final MIStoppedEvent fEvent; >+ FrameDataFromStoppedEvent(MIStoppedEvent event) { fEvent = event; } >+ @Override >+ protected MIFrame getMIFrame() { return fEvent.getFrame(); } >+ } >+ >+ // Retrieve the top stack frame from the stopped event only if the selected thread is the one on which stopped event >+ // is raised >+ if (fCachedStoppedEvent != null && >+ execDmc.equals(fCachedStoppedEvent.getDMContext()) && >+ miFrameDmc.fLevel == 0 && >+ fCachedStoppedEvent.getFrame() != null) >+ { >+ rm.setData(new FrameDataFromStoppedEvent(fCachedStoppedEvent)); >+ rm.done(); >+ return; >+ } >+ >+ // If not, retrieve the full list of frame data. >+ class FrameDataFromMIStackFrameListInfo extends FrameData { >+ private MIStackListFramesInfo fFrameDataCacheInfo; >+ private int fFrameIndex; >+ >+ FrameDataFromMIStackFrameListInfo(MIStackListFramesInfo info, int index) { >+ fFrameDataCacheInfo = info; >+ fFrameIndex = index; >+ } >+ >+ @Override >+ protected MIFrame getMIFrame() { return fFrameDataCacheInfo.getMIFrames()[fFrameIndex]; } >+ } >+ >+ fMICommandCache.execute( >+ new MIStackListFrames(execDmc, true), >+ new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ // Find the index to the correct MI frame object. >+ int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel); >+ if (idx == -1) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Create the data object. >+ rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx)); >+ rm.done(); >+ } >+ }); >+ } >+ >+ public void getArguments(final IFrameDMContext frameDmc, final DataRequestMonitor<IVariableDMContext[]> rm) { >+ final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ >+ // If requested frame is the top stack frame, try to retrieve it from >+ // the stopped event data. >+ if (frameDmc.getLevel() == 0 && >+ fCachedStoppedEvent != null && >+ fCachedStoppedEvent.getFrame() != null && >+ execDmc.equals(fCachedStoppedEvent.getDMContext()) && >+ fCachedStoppedEvent.getFrame().getArgs() != null) >+ { >+ rm.setData(makeVariableDMCs( >+ frameDmc, MIVariableDMC.Type.ARGUMENT, fCachedStoppedEvent.getFrame().getArgs().length)); >+ rm.done(); >+ return; >+ } >+ >+ // If not, retrieve the full list of frame data. >+ fMICommandCache.execute( >+ new MIStackListArguments(execDmc, true, true), >+ new DataRequestMonitor<MIStackListArgumentsInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ // Find the index to the correct MI frame object. >+ // Note: this is a short-cut, but it won't work once we implement retrieving >+ // partial lists of stack frames. >+ int idx = frameDmc.getLevel(); >+ if (idx == -1 || idx >= getData().getMIFrames().length) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Create the variable array out of MIArg array. >+ MIArg[] args = getData().getMIFrames()[idx].getArgs(); >+ if (args == null) args = new MIArg[0]; >+ rm.setData(makeVariableDMCs(frameDmc, MIVariableDMC.Type.ARGUMENT, args.length)); >+ rm.done(); >+ } >+ }); >+ } >+ >+ public void getVariableData(IVariableDMContext variableDmc, final DataRequestMonitor<IVariableDMData> rm) { >+ if (!(variableDmc instanceof MIVariableDMC)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + variableDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ final MIVariableDMC miVariableDmc = (MIVariableDMC)variableDmc; >+ >+ // Extract the frame DMC from the variable DMC. >+ final MIFrameDMC frameDmc = DMContexts.getAncestorOfType(variableDmc, MIFrameDMC.class); >+ if (frameDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No frame context found in " + variableDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ /** >+ * Same as with frame objects, this is a base class for the IVariableDMData object that uses an MIArg object to >+ * provide the data. Sub-classes must supply the MIArg object. >+ */ >+ class VariableData implements IVariableDMData { >+ private MIArg dsfMIArg; >+ VariableData(MIArg arg){ >+ dsfMIArg = arg; >+ } >+ public String getName() { return dsfMIArg.getName(); } >+ public String getValue() { return dsfMIArg.getValue(); } >+ @Override >+ public String toString() { return dsfMIArg.toString(); } >+ } >+ >+ // Check if the stopped event can be used to extract the variable value. >+ if (execDmc != null && miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT && >+ frameDmc.fLevel == 0 && fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null && >+ execDmc.equals(fCachedStoppedEvent.getDMContext()) && >+ fCachedStoppedEvent.getFrame().getArgs() != null) >+ { >+ if (miVariableDmc.fIndex >= fCachedStoppedEvent.getFrame().getArgs().length) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "Invalid variable " + miVariableDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ rm.setData(new VariableData(fCachedStoppedEvent.getFrame().getArgs()[miVariableDmc.fIndex])); >+ rm.done(); >+ return; >+ } >+ >+ if (miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT){ >+ fMICommandCache.execute( >+ new MIStackListArguments(execDmc, true, true), >+ new DataRequestMonitor<MIStackListArgumentsInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ // Find the correct frame and argument >+ if ( frameDmc.fLevel >= getData().getMIFrames().length || >+ miVariableDmc.fIndex >= getData().getMIFrames()[frameDmc.fLevel].getArgs().length ) >+ { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable " + miVariableDmc, null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Create the data object. >+ rm.setData(new VariableData(getData().getMIFrames()[frameDmc.fLevel].getArgs()[miVariableDmc.fIndex])); >+ rm.done(); >+ }}); >+ }//if >+ if (miVariableDmc.fType == MIVariableDMC.Type.LOCAL){ >+ fMICommandCache.execute( >+ new MIStackListLocals(frameDmc, true, true), >+ new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ >+ // Create the data object. >+ MIArg[] locals = getData().getLocals(); >+ if (locals.length > miVariableDmc.fIndex) { >+ rm.setData(new VariableData(locals[miVariableDmc.fIndex])); >+ } else { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable " + miVariableDmc, null)); //$NON-NLS-1$ >+ } >+ rm.done(); >+ } >+ }); >+ >+ }//if >+ >+ } >+ >+ private MIVariableDMC[] makeVariableDMCs(IFrameDMContext frame, MIVariableDMC.Type type, int count) { >+ MIVariableDMC[] variables = new MIVariableDMC[count]; >+ for (int i = 0; i < count; i++) { >+ variables[i]= new MIVariableDMC(this, frame, type, i); >+ } >+ return variables; >+ } >+ >+ private int findFrameIndex(MIFrame[] frames, int level) { >+ for (int idx = 0; idx < frames.length; idx++) { >+ if (frames[idx].getLevel() == level) { >+ return idx; >+ } >+ } >+ return -1; >+ } >+ >+ >+ public void getLocals(final IFrameDMContext frameDmc, final DataRequestMonitor<IVariableDMContext[]> rm) { >+ >+ final List<IVariableDMContext> localsList = new ArrayList<IVariableDMContext>(); >+ >+ final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ rm.setData( localsList.toArray(new IVariableDMContext[localsList.size()]) ); >+ rm.done(); >+ } >+ }; >+ countingRm.setDoneCount(2); >+ >+ getArguments( >+ frameDmc, >+ new DataRequestMonitor<IVariableDMContext[]>(getExecutor(), countingRm) { >+ @Override >+ protected void handleSuccess() { >+ localsList.addAll( Arrays.asList(getData()) ); >+ countingRm.done(); >+ } >+ }); >+ >+ fMICommandCache.execute( >+ new MIStackListLocals(frameDmc, true, true), >+ new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), countingRm) { >+ @Override >+ protected void handleSuccess() { >+ localsList.addAll( Arrays.asList( >+ makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)) ); >+ countingRm.done(); >+ } >+ }); >+ } >+ >+ public void getStackDepth(IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) { >+ >+ // Make sure we have an execution context (ideally a thread) >+ final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class); >+ if (execDmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ // Make sure the thread is stopped >+ if (!fMIRunControl.isSuspended(execDmc)) { >+ rm.setData(0); >+ rm.done(); >+ return; >+ } >+ >+ // Select the proper MI command variant >+ MIStackInfoDepth depthCommand = null; >+ if (maxDepth > 0) { >+ depthCommand = new MIStackInfoDepth(execDmc, true, maxDepth); >+ } >+ else { >+ depthCommand = new MIStackInfoDepth(execDmc); >+ } >+ >+ // And go... >+ fMICommandCache.execute( >+ depthCommand, >+ new DataRequestMonitor<MIStackInfoDepthInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ rm.setData(getData().getDepth()); >+ rm.done(); >+ } >+ }); >+ } >+ >+ // IServiceEventListener >+ @DsfServiceEventHandler >+ public void eventDispatched(IResumedDMEvent e) { >+ fMICommandCache.setContextAvailable(e.getDMContext(), false); >+ if (e.getReason() != StateChangeReason.STEP) { >+ fCachedStoppedEvent = null; >+ fMICommandCache.reset(); >+ } >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(ISuspendedDMEvent e) { >+ fMICommandCache.setContextAvailable(e.getDMContext(), true); >+ fMICommandCache.reset(); >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(IMIDMEvent e) { >+ MIEvent<? extends IDMContext> miEvent = e.getMIEvent(); >+ if (miEvent instanceof MIStoppedEvent) { >+ fCachedStoppedEvent = (MIStoppedEvent)miEvent; >+ } >+ } >+ >+} >Index: src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java >=================================================================== >RCS file: src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java >diff -N src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,254 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 QNX Software Systems and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * QNX Software Systems - Initial API and implementation >+ * Ericsson AB - Modified for DSF Reference Implementation >+ *******************************************************************************/ >+package org.eclipse.dd.mi.service.command.output; >+ >+import java.math.BigInteger; >+import java.util.List; >+import java.util.Vector; >+import java.util.regex.Matcher; >+import java.util.regex.Pattern; >+ >+import org.eclipse.dd.dsf.concurrent.Immutable; >+ >+/** >+ * GDB/MI thread list parsing. >+ * >+ * Example 1: >+ * >+ * -thread-info >+ * ^done,threads=[ >+ * {id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)", >+ * frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}], >+ * file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"}, >+ * running="0"}, >+ * {id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)", >+ * frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}], >+ * file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"}, >+ * running="0"} >+ * ],current-thread-id="2" >+ * >+ >+ * Example 2: >+ * >+ * -thread-info 2 >+ * ^done,threads=[ >+ * {id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)", >+ * frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}], >+ * file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"}, >+ * running="0"} >+ * ] >+ * >+ * >+ * Example 3 (non-stop): >+ * >+ * -thread-info >+ * ^done,threads=[ >+ * {id="2",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1"}, >+ * {id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)", >+ * frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}], >+ * file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"}, >+ * running="0"} >+ * ],current-thread-id="1" >+ */ >+public class MIThreadInfoInfo extends MIInfo { >+ >+ @Immutable >+ public class ThreadInfo { >+ >+ final private String fGdbId; >+ final private String fTargetId; >+ final private String fOsId; >+ final private ThreadFrame fTopFrame; >+ final private boolean fIsRunning; >+ >+ public ThreadInfo(String gdbId, String targetId, String osId, ThreadFrame topFrame, boolean isRunning) { >+ fGdbId = gdbId; >+ fTargetId = targetId; >+ fOsId = osId; >+ fTopFrame = topFrame; >+ fIsRunning = isRunning; >+ } >+ >+ public String getGdbId() { return fGdbId; } >+ public String getTargetId() { return fTargetId; } >+ public String getOsId() { return fOsId; } >+ public ThreadFrame getTopFrame() { return fTopFrame; } >+ public boolean isRunning() { return fIsRunning; } >+ } >+ >+ @Immutable >+ public class ThreadFrame { >+ final private int fStackLevel; >+ final private BigInteger fAddress; >+ final private String fFunction; >+ final private ThreadFrameFunctionArgs[] fArgs; >+ final private String fFileName; >+ final private String fFullName; >+ final private int fLineNumber; >+ >+ public ThreadFrame(int stackLevel, BigInteger address, String function, >+ ThreadFrameFunctionArgs[] args, String file, String fullName, int line) >+ { >+ fStackLevel = stackLevel; >+ fAddress = address; >+ fFunction = function; >+ fArgs = args; >+ fFileName = file; >+ fFullName = fullName; >+ fLineNumber = line; >+ } >+ >+ public int getStackLevel() { return fStackLevel; } >+ public BigInteger getAddress() { return fAddress; } >+ public String getFucntion() { return fFunction; } >+ public ThreadFrameFunctionArgs[] getArgs() { return fArgs; } >+ public String getFileName() { return fFileName; } >+ public String getFullName() { return fFullName; } >+ public int getLineNumber() { return fLineNumber; } >+ } >+ >+ @Immutable >+ public class ThreadFrameFunctionArgs { >+ } >+ >+ private int fCurrentThread = -1; >+ private List<ThreadInfo> fThreadInfoList = null; >+ private int[] fThreadList = null; >+ >+ public MIThreadInfoInfo(MIOutput out) { >+ super(out); >+ parse(); >+ } >+ >+ public int getCurrentThread() { >+ return fCurrentThread; >+ } >+ >+ public List<ThreadInfo> getThreadInfoList() { >+ return fThreadInfoList; >+ } >+ >+ public int[] getThreadList() { >+ return fThreadList; >+ } >+ >+ // General format: >+ // threads=[{...}],current-thread-id="n" >+ private void parse() { >+ if (isDone()) { >+ MIOutput out = getMIOutput(); >+ MIResultRecord rr = out.getMIResultRecord(); >+ if (rr != null) { >+ MIResult[] results = rr.getMIResults(); >+ for (int i = 0; i < results.length; i++) { >+ String var = results[i].getVariable(); >+ if (var.equals("threads")) { //$NON-NLS-1$ >+ MIValue val = results[i].getMIValue(); >+ if (val instanceof MIList) { >+ parseThreads((MIList) val); >+ } >+ } >+ else if (var.equals("current-thread-id")) { //$NON-NLS-1$ >+ MIValue value = results[i].getMIValue(); >+ if (value instanceof MIConst) { >+ String str = ((MIConst) value).getCString(); >+ try { >+ fCurrentThread = Integer.parseInt(str.trim()); >+ } catch (NumberFormatException e) { >+ fCurrentThread = -1; >+ } >+ } >+ } >+ } >+ } >+ } >+ if (fThreadInfoList == null) { >+ fThreadInfoList = new Vector<ThreadInfo>(0); >+ fThreadList = new int[0]; >+ } >+ } >+ >+ // General formats: >+ // id="n",target-id="Thread 0xb7c8ab90 (LWP 7010)",frame={...},running="0" >+ // id="n",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1" >+ private void parseThreads(MIList list) { >+ MIValue[] values = list.getMIValues(); >+ fThreadInfoList = new Vector<ThreadInfo>(values.length); >+ fThreadList = new int[values.length]; >+ >+ for (int i = 0; i < values.length; i++) { >+ MITuple value = (MITuple) values[i]; >+ MIResult[] results = value.getMIResults(); >+ >+ String gdbId = null; >+ String targetId = null; >+ String osId = null; >+ ThreadFrame topFrame = null; >+ boolean isRunning = false; >+ >+ for (int j = 0; j < results.length; j++) { >+ MIResult result = results[j]; >+ String var = result.getVariable(); >+ if (var.equals("id")) { //$NON-NLS-1$ >+ MIValue val = results[j].getMIValue(); >+ if (val instanceof MIConst) { >+ gdbId = ((MIConst) val).getCString(); >+ } >+ } >+ else if (var.equals("target-id")) { //$NON-NLS-1$ >+ MIValue val = results[j].getMIValue(); >+ if (val instanceof MIConst) { >+ targetId = ((MIConst) val).getCString(); >+ osId = parseOsId(targetId); >+ } >+ } >+ else if (var.equals("frame")) { //$NON-NLS-1$ >+ MIValue val = results[j].getMIValue(); >+ topFrame = parseFrame(val); >+ } >+ else if (var.equals("running")) { //$NON-NLS-1$ >+ MIValue val = results[j].getMIValue(); >+ if (val instanceof MIConst) { >+ String v = ((MIConst) val).getCString(); >+ isRunning = v.equals("1"); //$NON-NLS-1$ >+ } >+ } >+ } >+ >+ fThreadInfoList.add(new ThreadInfo(gdbId, targetId, osId, topFrame, isRunning)); >+ try { >+ fThreadList[i] = Integer.parseInt(gdbId); >+ } catch (NumberFormatException e) { >+ } >+ } >+ } >+ >+ // General format: >+ // "Thread 0xb7c8ab90 (LWP 7010)" >+ private String parseOsId(String str) { >+ Pattern pattern = Pattern.compile("(Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)", 0); //$NON-NLS-1$ >+ Matcher matcher = pattern.matcher(str); >+ if (matcher.find()) { >+ return matcher.group(4); >+ } >+ return null; >+ } >+ >+ // General format: >+ // level="0",addr="0x08048bba",func="func",args=[...],file="file.cc",fullname="/path/file.cc",line="26" >+ private ThreadFrame parseFrame(MIValue val) { >+ // TODO Auto-generated method stub >+ return null; >+ } >+ >+} >+ >Index: src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java >=================================================================== >RCS file: src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java >diff -N src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,42 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 QNX Software Systems and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * QNX Software Systems - Initial API and implementation >+ * Ericsson - Modified for new DSF Reference Implementation >+ *******************************************************************************/ >+ >+package org.eclipse.dd.mi.service.command.commands; >+ >+import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; >+import org.eclipse.dd.mi.service.command.output.MIOutput; >+import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo; >+ >+/** >+ * >+ * -thread-info [ thread-id ] >+ * >+ * Reports information about either a specific thread, if [thread-id] is present, >+ * or about all threads. When printing information about all threads, also reports >+ * the current thread. >+ * >+ */ >+public class MIThreadInfo extends MICommand<MIThreadInfoInfo> { >+ >+ public MIThreadInfo(IContainerDMContext dmc) { >+ super(dmc, "-thread-info"); //$NON-NLS-1$ >+ } >+ >+ public MIThreadInfo(IContainerDMContext dmc, int threadId) { >+ super(dmc, "-thread-info", new String[]{ Integer.toString(threadId) }); //$NON-NLS-1$ >+ } >+ >+ @Override >+ public MIThreadInfoInfo getResult(MIOutput out) { >+ return new MIThreadInfoInfo(out); >+ } >+} >Index: src/org/eclipse/dd/mi/service/MIRunControlNS.java >=================================================================== >RCS file: src/org/eclipse/dd/mi/service/MIRunControlNS.java >diff -N src/org/eclipse/dd/mi/service/MIRunControlNS.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/dd/mi/service/MIRunControlNS.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,897 @@ >+/******************************************************************************* >+ * 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 handling of multiple threads >+ *******************************************************************************/ >+ >+package org.eclipse.dd.mi.service; >+ >+import java.util.HashMap; >+import java.util.Map; >+ >+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.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.IStack.IFrameDMContext; >+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.commands.MIExecContinue; >+import org.eclipse.dd.mi.service.command.commands.MIExecFinish; >+import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt; >+import org.eclipse.dd.mi.service.command.commands.MIExecNext; >+import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction; >+import org.eclipse.dd.mi.service.command.commands.MIExecStep; >+import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction; >+import org.eclipse.dd.mi.service.command.commands.MIExecUntil; >+import org.eclipse.dd.mi.service.command.commands.MIThreadListIds; >+import org.eclipse.dd.mi.service.command.events.IMIDMEvent; >+import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; >+import org.eclipse.dd.mi.service.command.events.MIErrorEvent; >+import org.eclipse.dd.mi.service.command.events.MIEvent; >+import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent; >+import org.eclipse.dd.mi.service.command.events.MIRunningEvent; >+import org.eclipse.dd.mi.service.command.events.MISharedLibEvent; >+import org.eclipse.dd.mi.service.command.events.MISignalEvent; >+import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent; >+import org.eclipse.dd.mi.service.command.events.MIStoppedEvent; >+import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent; >+import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent; >+import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent; >+import org.eclipse.dd.mi.service.command.output.MIInfo; >+import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo; >+import org.osgi.framework.BundleContext; >+ >+/** >+ * Implementation note: This class implements event handlers for the events that >+ * are generated by this service itself. When the event is dispatched, these >+ * handlers will be called first, before any of the clients. These handlers >+ * update the service's internal state information to make them consistent with >+ * the events being issued. Doing this in the handlers as opposed to when the >+ * events are generated, guarantees that the state of the service will always be >+ * consistent with the events. The purpose of this pattern is to allow clients >+ * that listen to service events and track service state, to be perfectly in >+ * sync with the service state. >+ */ >+public class MIRunControlNS extends AbstractDsfService implements IMIRunControl >+{ >+ // This is an exact copy of the structures in MIRunControl. In an ideal world, >+ // it would be declared only once in IMIRunControl but this is real life and >+ // it has to be duplicated for the sake of backward compatibility. >+ // It sucks and leads to bloated, error-prone code but that's the way it is. >+ class MIExecutionDMCNS extends AbstractDMContext implements IMIExecutionDMContext >+ { >+ /** >+ * Integer ID that is used to identify the thread in the GDB/MI protocol. >+ */ >+ private final int fThreadId; >+ >+ /** >+ * Constructor for the context. It should not be called directly by clients. >+ * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)} >+ * to create instances of this context based on the thread ID. >+ * <p/> >+ * Classes extending {@link MIRunControl} may also extend this class to include >+ * additional information in the context. >+ * >+ * @param sessionId Session that this context belongs to. >+ * @param containerDmc The container that this context belongs to. >+ * @param threadId GDB/MI thread identifier. >+ */ >+ protected MIExecutionDMCNS(String sessionId, IContainerDMContext containerDmc, int threadId) { >+ super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]); >+ fThreadId = threadId; >+ } >+ >+ /** >+ * Returns the GDB/MI thread identifier of this context. >+ * @return >+ */ >+ public int getThreadId(){ >+ return fThreadId; >+ } >+ >+ @Override >+ public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ >+ >+ @Override >+ public boolean equals(Object obj) { >+ return super.baseEquals(obj) && ((MIExecutionDMCNS)obj).fThreadId == fThreadId; >+ } >+ >+ @Override >+ public int hashCode() { return super.baseHashCode() ^ fThreadId; } >+ } >+ >+ @Immutable >+ static class ExecutionData implements IExecutionDMData { >+ private final StateChangeReason fReason; >+ ExecutionData(StateChangeReason reason) { >+ fReason = reason; >+ } >+ public StateChangeReason getStateChangeReason() { return fReason; } >+ } >+ >+ /** >+ * Base class for events generated by the MI Run Control service. Most events >+ * generated by the MI Run Control service are directly caused by some MI event. >+ * Other services may need access to the extended MI data carried in the event. >+ * >+ * @param <V> DMC that this event refers to >+ * @param <T> MIInfo object that is the direct cause of this event >+ * @see MIRunControl >+ */ >+ @Immutable >+ static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V> >+ implements IDMEvent<V>, IMIDMEvent >+ { >+ final private T fMIInfo; >+ public RunControlEvent(V dmc, T miInfo) { >+ super(dmc); >+ fMIInfo = miInfo; >+ } >+ >+ public T getMIEvent() { return fMIInfo; } >+ } >+ >+ /** >+ * Indicates that the given thread has been suspended. >+ */ >+ @Immutable >+ static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent> >+ implements ISuspendedDMEvent >+ { >+ SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) { >+ super(ctx, miInfo); >+ } >+ >+ public StateChangeReason getReason() { >+ if (getMIEvent() instanceof MIBreakpointHitEvent) { >+ return StateChangeReason.BREAKPOINT; >+ } else if (getMIEvent() instanceof MISteppingRangeEvent) { >+ return StateChangeReason.STEP; >+ } else if (getMIEvent() instanceof MISharedLibEvent) { >+ return StateChangeReason.SHAREDLIB; >+ }else if (getMIEvent() instanceof MISignalEvent) { >+ return StateChangeReason.SIGNAL; >+ }else if (getMIEvent() instanceof MIWatchpointTriggerEvent) { >+ return StateChangeReason.WATCHPOINT; >+ }else if (getMIEvent() instanceof MIErrorEvent) { >+ return StateChangeReason.ERROR; >+ }else { >+ return StateChangeReason.USER_REQUEST; >+ } >+ } >+ } >+ >+ @Immutable >+ static class ContainerSuspendedEvent extends SuspendedEvent >+ implements IContainerSuspendedDMEvent >+ { >+ final IExecutionDMContext[] triggeringDmcs; >+ ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { >+ super(containerDmc, miInfo); >+ this.triggeringDmcs = triggeringDmc != null >+ ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >+ } >+ >+ public IExecutionDMContext[] getTriggeringContexts() { >+ return triggeringDmcs; >+ } >+ } >+ >+ @Immutable >+ static class ThreadSuspendedEvent extends SuspendedEvent >+ { >+ ThreadSuspendedEvent(IExecutionDMContext executionDmc, MIStoppedEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent> >+ implements IResumedDMEvent >+ { >+ ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) { >+ super(ctx, miInfo); >+ } >+ >+ public StateChangeReason getReason() { >+ switch(getMIEvent().getType()) { >+ case MIRunningEvent.CONTINUE: >+ return StateChangeReason.USER_REQUEST; >+ case MIRunningEvent.NEXT: >+ case MIRunningEvent.NEXTI: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.STEP: >+ case MIRunningEvent.STEPI: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.FINISH: >+ return StateChangeReason.STEP; >+ case MIRunningEvent.UNTIL: >+ case MIRunningEvent.RETURN: >+ break; >+ } >+ return StateChangeReason.UNKNOWN; >+ } >+ } >+ >+ @Immutable >+ static class ContainerResumedEvent extends ResumedEvent >+ implements IContainerResumedDMEvent >+ { >+ final IExecutionDMContext[] triggeringDmcs; >+ >+ ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { >+ super(containerDmc, miInfo); >+ this.triggeringDmcs = triggeringDmc != null >+ ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; >+ } >+ >+ public IExecutionDMContext[] getTriggeringContexts() { >+ return triggeringDmcs; >+ } >+ } >+ >+ @Immutable >+ static class ThreadResumedEvent extends ResumedEvent >+ { >+ ThreadResumedEvent(IExecutionDMContext executionDmc, MIRunningEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent> >+ implements IStartedDMEvent >+ { >+ StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ @Immutable >+ static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent> >+ implements IExitedDMEvent >+ { >+ ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { >+ super(executionDmc, miInfo); >+ } >+ } >+ >+ protected class MIThreadRunState { >+ // State flags >+ boolean fSuspended = false; >+ boolean fResumePending = false; >+ boolean fStepping = false; >+ StateChangeReason fStateChangeReason; >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // MIRunControlNS >+ /////////////////////////////////////////////////////////////////////////// >+ >+ private AbstractMIControl fConnection; >+ >+ // The command cache applies only for the thread-info command at the >+ // container (process) level and is *always* available in non-stop mode. >+ // The only thing to do is to reset it every time a thread is created/ >+ // terminated. >+ private CommandCache fMICommandCache; >+ >+ private boolean fTerminated = false; >+ >+ // ThreadStates indexed by the execution context >+ protected Map<IMIExecutionDMContext, MIThreadRunState> fThreadRunStates = new HashMap<IMIExecutionDMContext, MIThreadRunState>(); >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // Initialization and shutdown >+ /////////////////////////////////////////////////////////////////////////// >+ >+ public MIRunControlNS(DsfSession session) { >+ super(session); >+ } >+ >+ @Override >+ public void initialize(final RequestMonitor rm) { >+ super.initialize(new RequestMonitor(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ doInitialize(rm); >+ } >+ }); >+ } >+ >+ private void doInitialize(final RequestMonitor rm) { >+ fConnection = getServicesTracker().getService(AbstractMIControl.class); >+ fMICommandCache = new CommandCache(getSession(), fConnection); >+ fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true); >+ getSession().addServiceEventListener(this, null); >+ rm.done(); >+ } >+ >+ @Override >+ public void shutdown(final RequestMonitor rm) { >+ getSession().removeServiceEventListener(this); >+ fMICommandCache.reset(); >+ super.shutdown(rm); >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // AbstractDsfService >+ /////////////////////////////////////////////////////////////////////////// >+ >+ @Override >+ protected BundleContext getBundleContext() { >+ return MIPlugin.getBundleContext(); >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // IDMService >+ /////////////////////////////////////////////////////////////////////////// >+ >+ @SuppressWarnings("unchecked") >+ public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) { >+ if (dmc instanceof IExecutionDMContext) { >+ getExecutionData((IExecutionDMContext) dmc, (DataRequestMonitor<IExecutionDMData>) rm); >+ } else { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // IRunControl >+ /////////////////////////////////////////////////////////////////////////// >+ >+ // ------------------------------------------------------------------------ >+ // Suspend >+ // ------------------------------------------------------------------------ >+ >+ public boolean isSuspended(IExecutionDMContext context) { >+ >+ // Thread case >+ if (context instanceof MIExecutionDMCNS) { >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ return (threadState == null) ? false : !fTerminated && threadState.fSuspended; >+ } >+ >+ // Container case >+ if (context instanceof IContainerDMContext) { >+ boolean isSuspended = false; >+ for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) { >+ if (DMContexts.isAncestorOf(threadContext, context)) { >+ isSuspended |= isSuspended(threadContext); >+ } >+ } >+ return isSuspended; >+ } >+ >+ // Default case >+ return false; >+ } >+ >+ public void canSuspend(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) { >+ >+ // Thread case >+ if (context instanceof MIExecutionDMCNS) { >+ rm.setData(doCanSuspend(context)); >+ rm.done(); >+ return; >+ } >+ >+ // Container case >+ if (context instanceof IContainerDMContext) { >+ boolean canSuspend = false; >+ for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) { >+ if (DMContexts.isAncestorOf(threadContext, context)) { >+ canSuspend |= doCanSuspend(threadContext); >+ } >+ } >+ rm.setData(canSuspend); >+ rm.done(); >+ return; >+ } >+ >+ // Default case >+ rm.setData(false); >+ rm.done(); >+ } >+ >+ private boolean doCanSuspend(IExecutionDMContext context) { >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ return (threadState == null) ? false : !fTerminated && !threadState.fSuspended; >+ } >+ >+ public void suspend(IExecutionDMContext context, final RequestMonitor rm) { >+ >+ assert context != null; >+ >+ // Thread case >+ IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); >+ if (thread != null) { >+ doSuspendThread(thread, rm); >+ return; >+ } >+ >+ // Container case >+ IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class); >+ if (container != null) { >+ doSuspendContainer(container, rm); >+ return; >+ } >+ >+ // Default case >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ >+ private void doSuspendThread(IMIExecutionDMContext context, final RequestMonitor rm) { >+ >+ if (!doCanSuspend(context)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, >+ "Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ MIExecInterrupt cmd = new MIExecInterrupt(context, true); >+ fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } >+ >+ private void doSuspendContainer(IExecutionDMContext context, final RequestMonitor rm) { >+ MIExecInterrupt cmd = new MIExecInterrupt(context, true); >+ fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } >+ >+ // ------------------------------------------------------------------------ >+ // Resume >+ // ------------------------------------------------------------------------ >+ >+ public void canResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) { >+ >+ // Thread case >+ if (context instanceof MIExecutionDMCNS) { >+ rm.setData(doCanResume(context)); >+ rm.done(); >+ return; >+ } >+ >+ // Container case >+ if (context instanceof IContainerDMContext) { >+ boolean canSuspend = false; >+ for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) { >+ if (DMContexts.isAncestorOf(threadContext, context)) { >+ canSuspend |= doCanResume(threadContext); >+ } >+ } >+ rm.setData(canSuspend); >+ rm.done(); >+ return; >+ } >+ >+ // Default case >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ >+ private boolean doCanResume(IExecutionDMContext context) { >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ return (threadState == null) ? false : !fTerminated && threadState.fSuspended && !threadState.fResumePending; >+ } >+ >+ public void resume(IExecutionDMContext context, final RequestMonitor rm) { >+ >+ assert context != null; >+ >+ // Thread case >+ IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); >+ if (thread != null) { >+ doResumeThread(thread, rm); >+ return; >+ } >+ >+ // Container case >+ IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class); >+ if (container != null) { >+ doResumeContainer(container, rm); >+ return; >+ } >+ >+ // Default case >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ >+ private void doResumeThread(IMIExecutionDMContext context, final RequestMonitor rm) { >+ >+ if (!doCanResume(context)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ if (threadState == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ threadState.fResumePending = true; >+ >+ MIExecContinue cmd = new MIExecContinue(context, context.getThreadId()); >+ fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } >+ >+ private void doResumeContainer(IContainerDMContext context, final RequestMonitor rm) { >+ MIExecContinue cmd = new MIExecContinue(context, false); >+ fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } >+ >+ // ------------------------------------------------------------------------ >+ // Step >+ // ------------------------------------------------------------------------ >+ >+ public boolean isStepping(IExecutionDMContext context) { >+ >+ // If it's a thread, just look it up >+ if (context instanceof MIExecutionDMCNS) { >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ return (threadState == null) ? false : !fTerminated && threadState.fStepping; >+ } >+ >+ // Default case >+ return false; >+ } >+ >+ public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm) { >+ >+ // If it's a thread, just look it up >+ if (context instanceof MIExecutionDMCNS) { >+ canResume(context, rm); >+ return; >+ } >+ >+ // If it's a container, then we don't want to step it >+ rm.setData(false); >+ rm.done(); >+ } >+ >+ public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { >+ >+ assert context != null; >+ >+ IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); >+ if (dmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, >+ "Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ if (!doCanResume(context)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Cannot resume context", null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ if (threadState == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Given context: " + context + " can't be found.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ threadState.fResumePending = true; >+ threadState.fStepping = true; >+ >+ switch (stepType) { >+ case STEP_INTO: >+ fConnection.queueCommand(new MIExecStep(dmc, true), >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ break; >+ case STEP_OVER: >+ fConnection.queueCommand(new MIExecNext(dmc, true), >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ break; >+ case STEP_RETURN: >+ // The -exec-finish command operates on the selected stack frame, but here we always >+ // want it to operate on the stop stack frame. So we manually create a top-frame >+ // context to use with the MI command. >+ // We get a local instance of the stack service because the stack service can be shut >+ // down before the run control service is shut down. So it is possible for the >+ // getService() request below to return null. >+ MIStack stackService = getServicesTracker().getService(MIStack.class); >+ if (stackService != null) { >+ IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0); >+ fConnection.queueCommand(new MIExecFinish(topFrameDmc), >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } else { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, >+ "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ break; >+ case INSTRUCTION_STEP_INTO: >+ fConnection.queueCommand(new MIExecStepInstruction(dmc, true), >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ break; >+ case INSTRUCTION_STEP_OVER: >+ fConnection.queueCommand(new MIExecNextInstruction(dmc, true), >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ break; >+ default: >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, >+ INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ >+ rm.done(); >+ } >+ } >+ >+ // ------------------------------------------------------------------------ >+ // Run to line >+ // ------------------------------------------------------------------------ >+ >+ // Later add support for Address and function. >+ // skipBreakpoints is not used at the moment. Implement later >+ public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm) { >+ >+ assert context != null; >+ >+ IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); >+ if (dmc == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, >+ "Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ if (!doCanResume(context)) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Cannot resume context", null)); //$NON-NLS-1$ >+ rm.done(); >+ return; >+ } >+ >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ if (threadState == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, >+ "Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ threadState.fResumePending = true; >+ fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ >+ new DataRequestMonitor<MIInfo>(getExecutor(), rm)); >+ } >+ >+ // ------------------------------------------------------------------------ >+ // Support functions >+ // ------------------------------------------------------------------------ >+ >+ public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) { >+ fMICommandCache.execute(new MIThreadListIds(containerDmc), >+ new DataRequestMonitor<MIThreadListIdsInfo>(getExecutor(), rm) { >+ @Override >+ protected void handleSuccess() { >+ rm.setData(makeExecutionDMCs(containerDmc, getData())); >+ rm.done(); >+ } >+ }); >+ } >+ >+ private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerCtx, MIThreadListIdsInfo info) { >+ IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length]; >+ for (int i = 0; i < info.getThreadIds().length; i++) { >+ executionDmcs[i] = createMIExecutionContext(containerCtx, info.getThreadIds()[i]); >+ } >+ return executionDmcs; >+ } >+ >+ public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) { >+ MIThreadRunState threadState = fThreadRunStates.get(dmc); >+ if (threadState == null) { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,INVALID_HANDLE, >+ "Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ rm.done(); >+ return; >+ } >+ >+ if (dmc instanceof IMIExecutionDMContext) { >+ rm.setData(new ExecutionData(threadState.fSuspended ? threadState.fStateChangeReason : null)); >+ } else { >+ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, >+ "Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ rm.done(); >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // IMIRunControl >+ /////////////////////////////////////////////////////////////////////////// >+ >+ public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) { >+ return new MIExecutionDMCNS(getSession().getId(), container, threadId); >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // IMIRunControl >+ /////////////////////////////////////////////////////////////////////////// >+ >+ public CommandCache getCache() { >+ return fMICommandCache; >+ } >+ >+ protected AbstractMIControl getConnection() { >+ return fConnection; >+ } >+ >+ /////////////////////////////////////////////////////////////////////////// >+ // Event handlers >+ /////////////////////////////////////////////////////////////////////////// >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(final MIRunningEvent e) { >+ >+ IDMEvent<?> event = null; >+ >+ // If it's not an execution context (what else could it be?!?), just propagate it >+ IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (executionDmc == null) { >+ event = new ResumedEvent(e.getDMContext(), e); >+ getSession().dispatchEvent(event, getProperties()); >+ return; >+ } >+ >+ // It's a thread execution context (since we are in non-stop mode) >+ event = new ThreadResumedEvent(e.getDMContext(), e); >+ updateThreadState(executionDmc, (ThreadResumedEvent) event); >+ getSession().dispatchEvent(event, getProperties()); >+ fMICommandCache.reset(); >+ >+ // Find the container context, which is used in multi-threaded debugging. >+ IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class); >+ if (containerDmc != null) { >+ IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null; >+ event = new ContainerResumedEvent(containerDmc, e, triggeringCtx); >+ getSession().dispatchEvent(event, getProperties()); >+ } >+ } >+ >+ private void updateThreadState(IMIExecutionDMContext context, ThreadResumedEvent event) { >+ StateChangeReason reason = event.getReason(); >+ boolean isStepping = reason.equals(StateChangeReason.STEP); >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ if (threadState == null) { >+ threadState = new MIThreadRunState(); >+ fThreadRunStates.put(context, threadState); >+ } >+ threadState.fSuspended = false; >+ threadState.fResumePending = false; >+ threadState.fStateChangeReason = reason; >+ threadState.fStepping = isStepping; >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(final MIStoppedEvent e) { >+ >+ IDMEvent<?> event = null; >+ >+ // If it's not an execution context (what else could it be?!?), just propagate it >+ IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (executionDmc == null) { >+ event = new SuspendedEvent(e.getDMContext(), e); >+ getSession().dispatchEvent(event, getProperties()); >+ return; >+ } >+ >+ // It's a thread execution context (since we are in non-stop mode) >+ event = new ThreadSuspendedEvent(e.getDMContext(), e); >+ updateThreadState(executionDmc, (ThreadSuspendedEvent) event); >+ getSession().dispatchEvent(event, getProperties()); >+ fMICommandCache.reset(); >+ >+ // Find the container context, which is used in multi-threaded debugging. >+ IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class); >+ if (containerDmc != null) { >+ IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null; >+ event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx); >+ getSession().dispatchEvent(event, getProperties()); >+ } >+ } >+ >+ private void updateThreadState(IMIExecutionDMContext context, ThreadSuspendedEvent event) { >+ StateChangeReason reason = event.getReason(); >+ MIThreadRunState threadState = fThreadRunStates.get(context); >+ if (threadState == null) { >+ threadState = new MIThreadRunState(); >+ fThreadRunStates.put(context, threadState); >+ } >+ threadState.fSuspended = true; >+ threadState.fResumePending = false; >+ threadState.fStepping = false; >+ threadState.fStateChangeReason = reason; >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(final MIThreadCreatedEvent e) { >+ IContainerDMContext containerDmc = e.getDMContext(); >+ IMIExecutionDMContext executionCtx = null; >+ if (e.getId() != -1) { >+ executionCtx = createMIExecutionContext(containerDmc, e.getId()); >+ if (fThreadRunStates.get(executionCtx) == null) { >+ fThreadRunStates.put(executionCtx, new MIThreadRunState()); >+ } >+ } >+ getSession().dispatchEvent(new StartedDMEvent(executionCtx, e), getProperties()); >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(final MIThreadExitEvent e) { >+ IContainerDMContext containerDmc = e.getDMContext(); >+ IMIExecutionDMContext executionCtx = null; >+ if (e.getId() != -1) { >+ executionCtx = createMIExecutionContext(containerDmc, e.getId()); >+ fThreadRunStates.remove(executionCtx); >+ } >+ getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties()); >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(ThreadResumedEvent e) { >+ IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (context == null) { >+ return; >+ } >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(ThreadSuspendedEvent e) { >+ IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (context == null) { >+ return; >+ } >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(ContainerResumedEvent e) { >+ IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (context == null) { >+ return; >+ } >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(ContainerSuspendedEvent e) { >+ IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class); >+ if (context == null) { >+ return; >+ } >+ } >+ >+ @DsfServiceEventHandler >+ public void eventDispatched(MIGDBExitEvent e) { >+ fTerminated = true; >+ } >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 237556
:
107226
|
107235
|
107620
|
107674
|
107792
|
108117
|
108341
|
108373
|
108457
|
108503
|
108505