Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 237556 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/dd/tests/gdb/AllTests.java (-1 / +2 lines)
Lines 26-32 Link Here
26
        MIRunControlTest.class,
26
        MIRunControlTest.class,
27
        ExpressionServiceTest.class,
27
        ExpressionServiceTest.class,
28
        MIMemoryTest.class,
28
        MIMemoryTest.class,
29
        MIBreakpointsTest.class
29
        MIBreakpointsTest.class,
30
        MIDisassemblyTest.class,
30
        
31
        
31
        /* Add your test class here */
32
        /* Add your test class here */
32
        })
33
        })
(-)src/org/eclipse/dd/tests/gdb/GDBProcessesTest.java (-8 / +8 lines)
Lines 24-31 Link Here
24
import org.eclipse.dd.dsf.service.DsfServicesTracker;
24
import org.eclipse.dd.dsf.service.DsfServicesTracker;
25
import org.eclipse.dd.dsf.service.DsfSession;
25
import org.eclipse.dd.dsf.service.DsfSession;
26
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
26
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
27
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData;
27
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBProcessData;
28
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData;
28
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
29
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
29
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
30
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
30
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
31
import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor;
31
import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor;
Lines 91-98 Link Here
91
		/*
91
		/*
92
		 * Create a request monitor 
92
		 * Create a request monitor 
93
		 */
93
		 */
94
        final DataRequestMonitor<GDBProcessData> rm = 
94
        final DataRequestMonitor<IGDBProcessData> rm = 
95
        	new DataRequestMonitor<GDBProcessData>(fSession.getExecutor(), null) {
95
        	new DataRequestMonitor<IGDBProcessData>(fSession.getExecutor(), null) {
96
            @Override
96
            @Override
97
            protected void handleCompleted() {
97
            protected void handleCompleted() {
98
               if (isSuccess()) {
98
               if (isSuccess()) {
Lines 123-129 Link Here
123
        /*
123
        /*
124
         * Get process data 
124
         * Get process data 
125
         */
125
         */
126
        GDBProcessData processData = rm.getData();
126
        IGDBProcessData processData = rm.getData();
127
 
127
 
128
        if(processData == null)
128
        if(processData == null)
129
       	  Assert.fail("No process data is returned for Process DMC");
129
       	  Assert.fail("No process data is returned for Process DMC");
Lines 141-148 Link Here
141
	 */
141
	 */
142
	@Test
142
	@Test
143
	public void getThreadData() throws InterruptedException{
143
	public void getThreadData() throws InterruptedException{
144
        final DataRequestMonitor<GDBThreadData> rm = 
144
        final DataRequestMonitor<IGDBThreadData> rm = 
145
        	new DataRequestMonitor<GDBThreadData>(fSession.getExecutor(), null) {
145
        	new DataRequestMonitor<IGDBThreadData>(fSession.getExecutor(), null) {
146
            @Override
146
            @Override
147
            protected void handleCompleted() {
147
            protected void handleCompleted() {
148
               if (isSuccess()) {
148
               if (isSuccess()) {
Lines 166-172 Link Here
166
        fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
166
        fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
167
        assertTrue(fWait.getMessage(), fWait.isOK());
167
        assertTrue(fWait.getMessage(), fWait.isOK());
168
        
168
        
169
        GDBThreadData threadData = rm.getData();
169
        IGDBThreadData threadData = rm.getData();
170
        if(threadData == null)
170
        if(threadData == null)
171
       	 fail("Thread data not returned for thread id = " + fExecDmc.getThreadId());
171
       	 fail("Thread data not returned for thread id = " + fExecDmc.getThreadId());
172
        else{
172
        else{
(-)src/org/eclipse/dd/dsf/debug/service/IRunControl.java (-1 / +1 lines)
Lines 37-43 Link Here
37
    
37
    
38
    /**
38
    /**
39
     * Context representing a process, kernel, or some other logical container 
39
     * Context representing a process, kernel, or some other logical container 
40
     * for execution cotnexts, which by itself can perform run-control
40
     * for execution contexts, which by itself can perform run-control
41
     * operations. 
41
     * operations. 
42
     */
42
     */
43
43
(-)src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java (-4 / +5 lines)
Lines 379-386 Link Here
379
	public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException {
379
	public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException {
380
        // Drill for the actual DMC
380
        // Drill for the actual DMC
381
        IMemoryDMContext memoryDmc = null;
381
        IMemoryDMContext memoryDmc = null;
382
        IDMContext dmc = null;
382
        if (context instanceof IAdaptable) {
383
        if (context instanceof IAdaptable) {
383
            IDMContext dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class);
384
        	dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class);
384
            if (dmc != null) {
385
            if (dmc != null) {
385
                memoryDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class);
386
                memoryDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class);
386
            }
387
            }
Lines 425-431 Link Here
425
			// In case of failure, simply return 'null'
426
			// In case of failure, simply return 'null'
426
427
427
			// Resolve the expression
428
			// Resolve the expression
428
			blockAddress = resolveMemoryAddress(memoryDmc, expression);
429
			blockAddress = resolveMemoryAddress(dmc, expression);
429
			if (blockAddress == null) {
430
			if (blockAddress == null) {
430
				return null;
431
				return null;
431
			}
432
			}
Lines 451-457 Link Here
451
	// Helper functions
452
	// Helper functions
452
	///////////////////////////////////////////////////////////////////////////
453
	///////////////////////////////////////////////////////////////////////////
453
454
454
	private BigInteger resolveMemoryAddress(final IDMContext idmContext, final String expression) throws DebugException {
455
	private BigInteger resolveMemoryAddress(final IDMContext dmc, final String expression) throws DebugException {
455
456
456
		// Use a Query to "synchronize" the downstream calls
457
		// Use a Query to "synchronize" the downstream calls
457
		Query<BigInteger> query = new Query<BigInteger>() {
458
		Query<BigInteger> query = new Query<BigInteger>() {
Lines 461-467 Link Here
461
				final IExpressions expressionService = (IExpressions) fExpressionServiceTracker.getService();
462
				final IExpressions expressionService = (IExpressions) fExpressionServiceTracker.getService();
462
				if (expressionService != null) {
463
				if (expressionService != null) {
463
					// Create the expression
464
					// Create the expression
464
					final IExpressionDMContext expressionDMC = expressionService.createExpression(idmContext, expression);
465
					final IExpressionDMContext expressionDMC = expressionService.createExpression(dmc, expression);
465
					String formatId = IFormattedValues.HEX_FORMAT;
466
					String formatId = IFormattedValues.HEX_FORMAT;
466
					FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId);
467
					FormattedValueDMContext valueDmc = expressionService.getFormattedValueContext(expressionDMC, formatId);
467
	                expressionService.getFormattedExpressionValue(
468
	                expressionService.getFormattedExpressionValue(
(-)src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java (-5 / +5 lines)
Lines 20-27 Link Here
20
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
20
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
21
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
21
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
22
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext;
22
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext;
23
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
23
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl;
24
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData;
24
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
25
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
25
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
26
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
26
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
27
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
27
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
Lines 49-55 Link Here
49
    @Override
49
    @Override
50
    protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
50
    protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
51
        for (final ILabelUpdate update : updates) {
51
        for (final ILabelUpdate update : updates) {
52
        	final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class);
52
        	final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
53
            if ( runControl == null ) {
53
            if ( runControl == null ) {
54
                    handleFailedUpdate(update);
54
                    handleFailedUpdate(update);
55
                    continue;
55
                    continue;
Lines 78-84 Link Here
78
78
79
                    // We're in a new dispatch cycle, and we have to check whether the
79
                    // We're in a new dispatch cycle, and we have to check whether the
80
                    // service reference is still valid.
80
                    // service reference is still valid.
81
                    final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class);
81
                    final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
82
                    if ( runControl == null ) {
82
                    if ( runControl == null ) {
83
                        handleFailedUpdate(update);
83
                        handleFailedUpdate(update);
84
                        return;
84
                        return;
Lines 89-95 Link Here
89
                    // Retrieve the rest of the thread information
89
                    // Retrieve the rest of the thread information
90
                    runControl.getThreadData(
90
                    runControl.getThreadData(
91
                        dmc,
91
                        dmc,
92
                        new ViewerDataRequestMonitor<GDBThreadData>(getSession().getExecutor(), update) {
92
                        new ViewerDataRequestMonitor<IGDBThreadData>(getSession().getExecutor(), update) {
93
                            @Override
93
                            @Override
94
                            public void handleCompleted() {
94
                            public void handleCompleted() {
95
                                if (!isSuccess()) {
95
                                if (!isSuccess()) {
(-)src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java (-8 / +8 lines)
Lines 25-32 Link Here
25
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
25
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
26
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
26
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
27
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext;
27
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext;
28
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
28
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl;
29
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData;
29
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBProcessData;
30
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
30
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
31
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
31
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
32
import org.eclipse.dd.mi.service.command.MIInferiorProcess;
32
import org.eclipse.dd.mi.service.command.MIInferiorProcess;
Lines 72-78 Link Here
72
	
72
	
73
    @Override
73
    @Override
74
	protected void updateLabelInSessionThread(final ILabelUpdate update) {
74
	protected void updateLabelInSessionThread(final ILabelUpdate update) {
75
    	final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class);
75
    	final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
76
        if ( runControl == null ) {
76
        if ( runControl == null ) {
77
            handleFailedUpdate(update);
77
            handleFailedUpdate(update);
78
            return;
78
            return;
Lines 90-96 Link Here
90
        
90
        
91
        runControl.getProcessData(
91
        runControl.getProcessData(
92
            dmc,
92
            dmc,
93
            new ViewerDataRequestMonitor<GDBProcessData>(getExecutor(), update) {
93
            new ViewerDataRequestMonitor<IGDBProcessData>(getExecutor(), update) {
94
				@Override
94
				@Override
95
                public void handleCompleted() {
95
                public void handleCompleted() {
96
                    if (!isSuccess()) {
96
                    if (!isSuccess()) {
Lines 151-161 Link Here
151
                    	try {
151
                    	try {
152
                            getSession().getExecutor().execute(new DsfRunnable() {
152
                            getSession().getExecutor().execute(new DsfRunnable() {
153
                                public void run() {
153
                                public void run() {
154
                                	final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class);
154
                                	final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
155
                                	if ( runControl != null ) {
155
                                	if ( runControl != null ) {
156
                                		runControl.getProcessData(
156
                                		runControl.getProcessData(
157
                                		    procDmc,
157
                                		    procDmc,
158
                                		    new ViewerDataRequestMonitor<GDBProcessData>(runControl.getExecutor(), request) {
158
                                		    new ViewerDataRequestMonitor<IGDBProcessData>(runControl.getExecutor(), request) {
159
                                                @Override
159
                                                @Override
160
                                                protected void handleCompleted() {
160
                                                protected void handleCompleted() {
161
                                                    if ( getStatus().isOK() ) {
161
                                                    if ( getStatus().isOK() ) {
Lines 203-213 Link Here
203
                	try {
203
                	try {
204
                        getSession().getExecutor().execute(new DsfRunnable() {
204
                        getSession().getExecutor().execute(new DsfRunnable() {
205
                            public void run() {
205
                            public void run() {
206
                            	final GDBRunControl runControl = getServicesTracker().getService(GDBRunControl.class);
206
                            	final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
207
                            	if ( runControl != null ) {
207
                            	if ( runControl != null ) {
208
                            		runControl.getProcessData(
208
                            		runControl.getProcessData(
209
                            		    procDmc,
209
                            		    procDmc,
210
                            		    new ViewerDataRequestMonitor<GDBProcessData>(runControl.getExecutor(), request) {
210
                            		    new ViewerDataRequestMonitor<IGDBProcessData>(runControl.getExecutor(), request) {
211
                                            @Override
211
                                            @Override
212
                                            protected void handleCompleted() {
212
                                            protected void handleCompleted() {
213
                                                if ( getStatus().isOK() ) {
213
                                                if ( getStatus().isOK() ) {
(-)src/org/eclipse/dd/gdb/internal/ui/launching/GdbDebuggerPage.java (+31 lines)
Lines 45-50 Link Here
45
	protected TabFolder fTabFolder;
45
	protected TabFolder fTabFolder;
46
	protected Text fGDBCommandText;
46
	protected Text fGDBCommandText;
47
	protected Text fGDBInitText;
47
	protected Text fGDBInitText;
48
	protected Button fNonStopCheckBox;
48
	private IMILaunchConfigurationComponent fSolibBlock;
49
	private IMILaunchConfigurationComponent fSolibBlock;
49
	private boolean fIsInitializing = false;
50
	private boolean fIsInitializing = false;
50
51
Lines 64-69 Link Here
64
				                   IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
65
				                   IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
65
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, 
66
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, 
66
				                   IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT);
67
				                   IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT);
68
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
69
				                   IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT);
70
67
		if (fSolibBlock != null)
71
		if (fSolibBlock != null)
68
			fSolibBlock.setDefaults(configuration);
72
			fSolibBlock.setDefaults(configuration);
69
	}
73
	}
Lines 86-91 Link Here
86
		setInitializing(true);
90
		setInitializing(true);
87
		String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT;
91
		String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT;
88
		String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT;
92
		String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT;
93
		boolean nonStopMode = IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT;
94
89
		try {
95
		try {
90
			gdbCommand = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
96
			gdbCommand = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
91
					                                IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
97
					                                IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
Lines 99-108 Link Here
99
		catch(CoreException e) {
105
		catch(CoreException e) {
100
		}
106
		}
101
107
108
		try {
109
			nonStopMode = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
110
					                                 IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT);
111
		}
112
		catch(CoreException e) {
113
		}
114
102
		if (fSolibBlock != null)
115
		if (fSolibBlock != null)
103
			fSolibBlock.initializeFrom(configuration);
116
			fSolibBlock.initializeFrom(configuration);
104
		fGDBCommandText.setText(gdbCommand);
117
		fGDBCommandText.setText(gdbCommand);
105
		fGDBInitText.setText(gdbInit);
118
		fGDBInitText.setText(gdbInit);
119
		fNonStopCheckBox.setSelection(nonStopMode);
106
120
107
		setInitializing(false); 
121
		setInitializing(false); 
108
	}
122
	}
Lines 112-117 Link Here
112
				                   fGDBCommandText.getText().trim());
126
				                   fGDBCommandText.getText().trim());
113
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
127
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
114
				                   fGDBInitText.getText().trim());
128
				                   fGDBInitText.getText().trim());
129
		configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
130
				                   fNonStopCheckBox.getSelection());
115
131
116
		if (fSolibBlock != null)
132
		if (fSolibBlock != null)
117
			fSolibBlock.performApply(configuration);
133
			fSolibBlock.performApply(configuration);
Lines 242-249 Link Here
242
				fGDBInitText.setText(res);
258
				fGDBInitText.setText(res);
243
			}
259
			}
244
		});
260
		});
261
262
		// TODO: Fetch the string from LaunchUIMessages
263
		// TODO: Ideally, this field should be disabled if the back-end doesn't support non-stop debugging
264
		// 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 
265
		// Button fNonStopButton = ControlFactory.createCheckBox(subComp, LaunchUIMessages.getString( "GDBDebuggerPage.15") ); //$NON-NLS-1$
266
		fNonStopCheckBox = ControlFactory.createCheckBox(subComp, LaunchUIMessages.getString("GDBDebuggerPage.13")); //$NON-NLS-1$
267
		fNonStopCheckBox.setEnabled(false);
268
		fNonStopCheckBox.addSelectionListener( new SelectionAdapter() {
269
				@Override
270
				public void widgetSelected(SelectionEvent e) {
271
					updateLaunchConfigurationDialog();
272
				}
273
			});
274
		
245
		label = ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.9"), //$NON-NLS-1$
275
		label = ControlFactory.createLabel(subComp, LaunchUIMessages.getString("GDBDebuggerPage.9"), //$NON-NLS-1$
246
				200, SWT.DEFAULT, SWT.WRAP);
276
				200, SWT.DEFAULT, SWT.WRAP);
277
247
		gd = new GridData(GridData.FILL_HORIZONTAL);
278
		gd = new GridData(GridData.FILL_HORIZONTAL);
248
		gd.horizontalSpan = 3;
279
		gd.horizontalSpan = 3;
249
		gd.widthHint = 200;
280
		gd.widthHint = 200;
(-)src/org/eclipse/dd/gdb/internal/ui/launching/LaunchUIMessages.properties (+1 lines)
Lines 24-29 Link Here
24
GDBDebuggerPage.10=Shared Libraries
24
GDBDebuggerPage.10=Shared Libraries
25
GDBDebuggerPage.11=Protocol:
25
GDBDebuggerPage.11=Protocol:
26
GDBDebuggerPage.12=Default
26
GDBDebuggerPage.12=Default
27
GDBDebuggerPage.13=Non-stop mode (Note: Requires non-stop GDB)
27
StandardGDBDebuggerPage.0=Debugger executable must be specified.
28
StandardGDBDebuggerPage.0=Debugger executable must be specified.
28
StandardGDBDebuggerPage.1=GDB Debugger Options
29
StandardGDBDebuggerPage.1=GDB Debugger Options
29
StandardGDBDebuggerPage.2=Main
30
StandardGDBDebuggerPage.2=Main
(-)src/org/eclipse/dd/gdb/internal/ui/breakpoints/GdbThreadFilterEditor.java (-5 / +5 lines)
Lines 30-37 Link Here
30
import org.eclipse.dd.dsf.service.DsfSession;
30
import org.eclipse.dd.dsf.service.DsfSession;
31
import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension;
31
import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension;
32
import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch;
32
import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch;
33
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
33
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl;
34
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData;
34
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
35
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
35
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
36
import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin;
36
import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin;
37
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
37
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
Lines 493-504 Link Here
493
                    return;
493
                    return;
494
                }
494
                }
495
495
496
                ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), GDBRunControl.class
496
                ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IGDBRunControl.class
497
                    .getName(), null);
497
                    .getName(), null);
498
                tracker.open();
498
                tracker.open();
499
                GDBRunControl runControl = (GDBRunControl) tracker.getService();
499
                IGDBRunControl runControl = (IGDBRunControl) tracker.getService();
500
                if (runControl != null) {
500
                if (runControl != null) {
501
                    runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor<GDBThreadData>(
501
                    runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor<IGDBThreadData>(
502
                        ImmediateExecutor.getInstance(), rm) {
502
                        ImmediateExecutor.getInstance(), rm) {
503
                        @Override
503
                        @Override
504
                        protected void handleSuccess() {
504
                        protected void handleSuccess() {
(-)src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControl.java (-9 / +12 lines)
Lines 29-47 Link Here
29
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
29
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
30
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
30
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
31
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
31
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
32
import org.eclipse.dd.mi.service.IMIRunControl;
32
import org.eclipse.dd.mi.service.MIRunControl;
33
import org.eclipse.dd.mi.service.MIRunControl;
33
import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads;
34
import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads;
34
import org.eclipse.dd.mi.service.command.events.MIEvent;
35
import org.eclipse.dd.mi.service.command.events.MIEvent;
35
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
36
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
36
import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo;
37
import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo;
37
public class GDBRunControl extends MIRunControl {
38
38
39
    /**
39
public class GDBRunControl extends MIRunControl implements IGDBRunControl {
40
41
	/**
40
     * Implement a custom execution data for threads in order to provide additional 
42
     * Implement a custom execution data for threads in order to provide additional 
41
     * information.  This object can be made separate from IExecutionDMData after
43
     * information.  This object can be made separate from IExecutionDMData after
42
     * the deprecated method: IDMService.getModelData() is no longer used.  
44
     * the deprecated method: IDMService.getModelData() is no longer used.  
43
     */
45
     */
44
    public static class GDBThreadData {
46
    public static class GDBThreadData implements IGDBThreadData {
45
        private final String fId;
47
        private final String fId;
46
        private final String fName;
48
        private final String fName;
47
49
Lines 63-69 Link Here
63
     * information.  This object can be made separate from IExecutionDMData after
65
     * information.  This object can be made separate from IExecutionDMData after
64
     * the deprecated method: IDMService.getModelData() is no longer used.  
66
     * the deprecated method: IDMService.getModelData() is no longer used.  
65
     */
67
     */
66
    public static class GDBProcessData {
68
    public static class GDBProcessData implements IGDBProcessData {
67
        private final String fName;
69
        private final String fName;
68
        
70
        
69
        GDBProcessData(String name) {
71
        GDBProcessData(String name) {
Lines 74-80 Link Here
74
            return fName;
76
            return fName;
75
        }
77
        }
76
    }
78
    }
77
    
79
78
    private GDBControl fGdb;
80
    private GDBControl fGdb;
79
    
81
    
80
	// Record list of execution contexts
82
	// Record list of execution contexts
Lines 98-105 Link Here
98
    private void doInitialize(final RequestMonitor requestMonitor) {
100
    private void doInitialize(final RequestMonitor requestMonitor) {
99
    	
101
    	
100
        fGdb = getServicesTracker().getService(GDBControl.class);
102
        fGdb = getServicesTracker().getService(GDBControl.class);
101
        register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>());
103
        register(new String[]{IRunControl.class.getName(), 
102
104
        		IMIRunControl.class.getName(),  MIRunControl.class.getName(), 
105
        		IGDBRunControl.class.getName(), GDBRunControl.class.getName()}, new Hashtable<String,String>());
103
        requestMonitor.done();
106
        requestMonitor.done();
104
    }
107
    }
105
108
Lines 149-160 Link Here
149
		super.getExecutionContexts(c, rm1);
152
		super.getExecutionContexts(c, rm1);
150
    }
153
    }
151
154
152
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<GDBProcessData> rm) {
155
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) {
153
        rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
156
        rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
154
        rm.done();
157
        rm.done();
155
	}
158
	}
156
	
159
	
157
	public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<GDBThreadData> rm) {
160
	public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> rm) {
158
        IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
161
        IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
159
        assert containerDmc != null; // Every exec context should have a container as an ancestor.
162
        assert containerDmc != null; // Every exec context should have a container as an ancestor.
160
        getCache().execute(new CLIInfoThreads(containerDmc),
163
        getCache().execute(new CLIInfoThreads(containerDmc),
(-)src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java (-1 / +22 lines)
Lines 37-42 Link Here
37
import org.eclipse.dd.gdb.internal.GdbPlugin;
37
import org.eclipse.dd.gdb.internal.GdbPlugin;
38
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
38
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
39
import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactory;
39
import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactory;
40
import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactoryNS;
40
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
41
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
41
import org.eclipse.debug.core.DebugException;
42
import org.eclipse.debug.core.DebugException;
42
import org.eclipse.debug.core.ILaunch;
43
import org.eclipse.debug.core.ILaunch;
Lines 56-62 Link Here
56
{
57
{
57
    public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$
58
    public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$
58
        
59
        
59
    public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
60
	private boolean isNonStopSession = false;
61
62
	public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
60
		if ( monitor == null ) {
63
		if ( monitor == null ) {
61
			monitor = new NullProgressMonitor();
64
			monitor = new NullProgressMonitor();
62
		}
65
		}
Lines 167-172 Link Here
167
    	return SessionType.LOCAL;
170
    	return SessionType.LOCAL;
168
    }
171
    }
169
    
172
    
173
	private boolean isNonStopSession(ILaunchConfiguration config) {
174
		try {
175
			boolean nonStopMode = config.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
176
                    IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT);
177
    		return nonStopMode;
178
    	} catch (CoreException e) {    		
179
    	}
180
    	return false;
181
    }
182
    
170
	private boolean getIsAttach(ILaunchConfiguration config) {
183
	private boolean getIsAttach(ILaunchConfiguration config) {
171
    	try {
184
    	try {
172
    		String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
185
    		String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
Lines 202-207 Link Here
202
        // the adapters will be created for the whole session, including 
215
        // the adapters will be created for the whole session, including 
203
        // the source lookup adapter.
216
        // the source lookup adapter.
204
        
217
        
218
		isNonStopSession = isNonStopSession(configuration);
219
205
        GdbLaunch launch = new GdbLaunch(configuration, mode, null);
220
        GdbLaunch launch = new GdbLaunch(configuration, mode, null);
206
        launch.initialize();
221
        launch.initialize();
207
        launch.setSourceLocator(getSourceLocator(configuration, launch.getSession()));
222
        launch.setSourceLocator(getSourceLocator(configuration, launch.getSession()));
Lines 314-319 Link Here
314
	}
329
	}
315
	
330
	
316
	private IDsfDebugServicesFactory newServiceFactory(String version) {
331
	private IDsfDebugServicesFactory newServiceFactory(String version) {
332
333
		// TODO: Fix version number once non-stop GDB is delivered
334
		if (isNonStopSession && version.startsWith("6.8.50.20080327")) { //$NON-NLS-1$
335
			return new GdbDebugServicesFactoryNS(version);
336
		}
337
317
		if (version.startsWith("6.6") ||  //$NON-NLS-1$
338
		if (version.startsWith("6.6") ||  //$NON-NLS-1$
318
			version.startsWith("6.7") ||  //$NON-NLS-1$
339
			version.startsWith("6.7") ||  //$NON-NLS-1$
319
			version.startsWith("6.8")) {  //$NON-NLS-1$
340
			version.startsWith("6.8")) {  //$NON-NLS-1$
(-)src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java (+11 lines)
Lines 49-54 Link Here
49
	public static final String ATTR_GDB_INIT = GdbPlugin.PLUGIN_ID + ".GDB_INIT"; //$NON-NLS-1$
49
	public static final String ATTR_GDB_INIT = GdbPlugin.PLUGIN_ID + ".GDB_INIT"; //$NON-NLS-1$
50
50
51
	/**
51
	/**
52
	 * Launch configuration attribute key. Boolean value to set the non-stop mode
53
	 * Debuger/gdb/MI property.
54
	 */
55
	public static final String ATTR_DEBUGGER_NON_STOP = GdbPlugin.PLUGIN_ID + ".NON_STOP"; //$NON-NLS-1$
56
57
	/**
52
	 * Launch configuration attribute key. Boolean value to set the 'automatically load shared library symbols' flag of the debugger.
58
	 * Launch configuration attribute key. Boolean value to set the 'automatically load shared library symbols' flag of the debugger.
53
	 */
59
	 */
54
	public static final String ATTR_DEBUGGER_AUTO_SOLIB = GdbPlugin.PLUGIN_ID + ".AUTO_SOLIB"; //$NON-NLS-1$
60
	public static final String ATTR_DEBUGGER_AUTO_SOLIB = GdbPlugin.PLUGIN_ID + ".AUTO_SOLIB"; //$NON-NLS-1$
Lines 79-84 Link Here
79
	public static final String DEBUGGER_GDB_INIT_DEFAULT = ".gdbinit"; //$NON-NLS-1$
85
	public static final String DEBUGGER_GDB_INIT_DEFAULT = ".gdbinit"; //$NON-NLS-1$
80
86
81
	/**
87
	/**
88
	 * Launch configuration attribute value. The key is ATTR_DEBUGGER_NON_STOP.
89
	 */
90
	public static final boolean DEBUGGER_NON_STOP_DEFAULT = false;
91
92
	/**
82
	 * Launch configuration attribute value. The key is ATTR_DEBUGGER_AUTO_SOLIB.
93
	 * Launch configuration attribute value. The key is ATTR_DEBUGGER_AUTO_SOLIB.
83
	 */
94
	 */
84
	public static final boolean DEBUGGER_AUTO_SOLIB_DEFAULT = true;
95
	public static final boolean DEBUGGER_AUTO_SOLIB_DEFAULT = true;
(-)src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java (-1 / +1 lines)
Lines 179-185 Link Here
179
     * More strongly typed version of {@link #getControlDMContext()}.
179
     * More strongly typed version of {@link #getControlDMContext()}.
180
     */
180
     */
181
    public GDBControlDMContext getGDBDMContext() {
181
    public GDBControlDMContext getGDBDMContext() {
182
        return (GDBControlDMContext)getControlDMContext();
182
        return (GDBControlDMContext) getControlDMContext();
183
    }
183
    }
184
184
185
    public SessionType getSessionType() { 
185
    public SessionType getSessionType() { 
(-)src/org/eclipse/dd/gdb/internal/provisional/service/IGDBRunControl.java (+41 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *     Ericsson			  - Modified for additional functionality
11
 *******************************************************************************/
12
package org.eclipse.dd.gdb.internal.provisional.service;
13
14
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
15
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
16
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.IMIRunControl;
18
19
/**
20
 * This interface provides access to controlling and monitoring the execution 
21
 * state of a process being debugged.  This interface does not actually 
22
 * provide methods for creating or destroying execution contexts, it doesn't
23
 * even have methods for getting labels.  That's because it is expected that
24
 * higher level services, ones that deal with processes, kernels, or target 
25
 * features will provide that functionality. 
26
 */
27
public interface IGDBRunControl extends IMIRunControl
28
{
29
    public interface IGDBThreadData {
30
        public String getName();
31
        public String getId(); 
32
        public boolean isDebuggerAttached();
33
    }
34
35
    public interface IGDBProcessData {
36
        public String getName();
37
    }
38
39
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm);
40
    public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> dataRequestMonitor);
41
}
(-)src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Ericsson and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Ericsson - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.dd.gdb.internal.provisional.service;
12
13
import org.eclipse.dd.dsf.debug.service.IRunControl;
14
import org.eclipse.dd.dsf.debug.service.IStack;
15
import org.eclipse.dd.dsf.service.DsfSession;
16
import org.eclipse.dd.mi.service.MIStackNS;
17
18
public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory {
19
20
	public GdbDebugServicesFactoryNS(String version) {
21
		super(version);
22
	}
23
		
24
	@Override
25
	protected IStack createStackService(DsfSession session) {
26
		return new MIStackNS(session);
27
	}
28
	
29
	@Override
30
	protected IRunControl createRunControlService(DsfSession session) {
31
		return new GDBRunControlNS(session);
32
	}
33
}
(-)src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java (+129 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *     Ericsson AB		  - Modified for additional functionality	
11
 *******************************************************************************/
12
13
package org.eclipse.dd.gdb.internal.provisional.service;
14
15
16
import java.util.Hashtable;
17
18
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
19
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
20
import org.eclipse.dd.dsf.datamodel.DMContexts;
21
import org.eclipse.dd.dsf.debug.service.IRunControl;
22
import org.eclipse.dd.dsf.service.DsfSession;
23
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
24
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
25
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
26
import org.eclipse.dd.mi.service.IMIRunControl;
27
import org.eclipse.dd.mi.service.MIRunControlNS;
28
import org.eclipse.dd.mi.service.command.commands.MIThreadInfo;
29
import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo;
30
31
public class GDBRunControlNS extends MIRunControlNS implements IGDBRunControl 
32
{
33
	/**
34
     * Implement a custom execution data for threads in order to provide additional 
35
     * information.  This object can be made separate from IExecutionDMData after
36
     * the deprecated method: IDMService.getModelData() is no longer used.  
37
     */
38
	private static class GDBThreadData implements IGDBThreadData {
39
        private final String fId;
40
        private final String fName;
41
42
        GDBThreadData(String id, String name) {
43
            fId = id;
44
            fName = name;
45
        }
46
        
47
        public String getName() {
48
            return fName; 
49
        }
50
        public String getId() { return fId; } 
51
52
        public boolean isDebuggerAttached() { return true; }
53
    }
54
55
    /**
56
     * Implement a custom execution data the process in order to provide additional 
57
     * information.  This object can be made separate from IExecutionDMData after
58
     * the deprecated method: IDMService.getModelData() is no longer used.  
59
     */
60
    private static class GDBProcessData implements IGDBProcessData {
61
        private final String fName;
62
        
63
        GDBProcessData(String name) {
64
            fName = name;
65
        }
66
        
67
        public String getName() {
68
            return fName;
69
        }
70
    }
71
72
    private GDBControl fGdb;
73
    
74
    public GDBRunControlNS(DsfSession session) {
75
        super(session);
76
    }
77
    
78
    @Override
79
    public void initialize(final RequestMonitor requestMonitor) {
80
        super.initialize(
81
            new RequestMonitor(getExecutor(), requestMonitor) { 
82
                @Override
83
                public void handleSuccess() {
84
                    doInitialize(requestMonitor);
85
                }});
86
    }
87
88
    private void doInitialize(final RequestMonitor requestMonitor) {
89
90
		fGdb = getServicesTracker().getService(GDBControl.class);
91
        register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName(), IGDBRunControl.class.getName()}, new Hashtable<String,String>());
92
93
        requestMonitor.done();
94
    }
95
96
    @Override
97
    public void shutdown(final RequestMonitor requestMonitor) {
98
        unregister();
99
        super.shutdown(requestMonitor);
100
    }
101
102
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) {
103
        rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
104
        rm.done();
105
	}
106
	
107
	public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> rm) {
108
		IContainerDMContext containerDmc =  DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
109
        getCache().execute(new MIThreadInfo(containerDmc, execDmc.getThreadId()),
110
                new DataRequestMonitor<MIThreadInfoInfo>(getExecutor(), rm) {
111
                    @Override
112
                    protected void handleSuccess() {
113
                        rm.setData(createThreadInfo(execDmc, getData()));
114
                        rm.done();
115
                    }
116
                });
117
	}
118
119
	private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, MIThreadInfoInfo info) {
120
		// There should be only 1 thread in the result, but just in case...
121
		for (MIThreadInfoInfo.ThreadInfo thread : info.getThreadInfoList()) {
122
			if (Integer.parseInt(thread.getGdbId()) == dmc.getThreadId()){
123
				return new GDBThreadData(thread.getOsId(), "");        //$NON-NLS-1$
124
			}
125
		}
126
		return  new GDBThreadData("", "");  //$NON-NLS-1$ //$NON-NLS-2$
127
	}
128
129
}
(-)src/org/eclipse/dd/mi/service/command/events/MIBreakpointHitEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 40-46 Link Here
40
    }
40
    }
41
41
42
    public static MIBreakpointHitEvent parse(
42
    public static MIBreakpointHitEvent parse(
43
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
43
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
44
    { 
44
    { 
45
        int bkptno = -1;
45
        int bkptno = -1;
46
46
(-)src/org/eclipse/dd/mi/service/command/events/MILocationReachedEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
21
21
Lines 30-36 Link Here
30
    }
30
    }
31
31
32
    public static MILocationReachedEvent parse(
32
    public static MILocationReachedEvent parse(
33
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
33
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
34
    {
34
    {
35
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
35
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
36
        return new MILocationReachedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
36
        return new MILocationReachedEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
(-)src/org/eclipse/dd/mi/service/command/events/MIThreadCreatedEvent.java (+24 lines)
Lines 14-19 Link Here
14
14
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIConst;
18
import org.eclipse.dd.mi.service.command.output.MIResult;
19
import org.eclipse.dd.mi.service.command.output.MIValue;
17
20
18
21
19
/**
22
/**
Lines 37-40 Link Here
37
    public int getId() {
40
    public int getId() {
38
        return tid;
41
        return tid;
39
    }
42
    }
43
44
    public static MIThreadCreatedEvent parse(IContainerDMContext ctx, int token, MIResult[] results)
45
    {
46
    	for (int i = 0; i < results.length; i++) {
47
    		String var = results[i].getVariable();
48
    		MIValue val = results[i].getMIValue();
49
    		if (var.equals("id")) { //$NON-NLS-1$
50
    			if (val instanceof MIConst) {
51
    				try { 
52
    					int thread = Integer.parseInt(((MIConst) val).getString());
53
    					return new MIThreadCreatedEvent(ctx, token, thread);
54
    				}
55
    				catch (NumberFormatException e) {
56
    					return null;
57
    				}
58
    			}
59
    		}
60
    	}
61
62
    	return null;
63
    }
40
}
64
}
(-)src/org/eclipse/dd/mi/service/command/events/MISharedLibEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
21
21
Lines 30-36 Link Here
30
    }
30
    }
31
31
32
    public static MIStoppedEvent parse(
32
    public static MIStoppedEvent parse(
33
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
33
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
34
    {
34
    {
35
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
35
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
36
        return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
36
        return new MISharedLibEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
(-)src/org/eclipse/dd/mi/service/command/events/MIThreadExitEvent.java (+24 lines)
Lines 14-19 Link Here
14
14
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIConst;
18
import org.eclipse.dd.mi.service.command.output.MIResult;
19
import org.eclipse.dd.mi.service.command.output.MIValue;
17
20
18
21
19
/**
22
/**
Lines 37-40 Link Here
37
    public int getId() {
40
    public int getId() {
38
        return tid;
41
        return tid;
39
    }
42
    }
43
    
44
    public static MIThreadExitEvent parse(IContainerDMContext ctx, int token, MIResult[] results)
45
    {
46
    	for (int i = 0; i < results.length; i++) {
47
    		String var = results[i].getVariable();
48
    		MIValue val = results[i].getMIValue();
49
    		if (var.equals("id")) { //$NON-NLS-1$
50
    			if (val instanceof MIConst) {
51
    				try { 
52
    					int thread = Integer.parseInt(((MIConst) val).getString());
53
    					return new MIThreadExitEvent(ctx, token, thread);
54
    				}
55
    				catch (NumberFormatException e) {
56
    					return null;
57
    				}
58
    			}
59
    		}
60
    	}
61
62
    	return null;
63
    }
40
}
64
}
(-)src/org/eclipse/dd/mi/service/command/events/MISteppingRangeEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
19
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
20
import org.eclipse.dd.mi.service.command.output.MIResult;
21
21
Lines 31-37 Link Here
31
    }
31
    }
32
32
33
    public static MISteppingRangeEvent parse(
33
    public static MISteppingRangeEvent parse(
34
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
34
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
35
    {
35
    {
36
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
36
        MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(runControl, containerDmc, token, results); 
37
        return new MISteppingRangeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
37
        return new MISteppingRangeEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame());
(-)src/org/eclipse/dd/mi/service/command/events/MISignalEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 49-55 Link Here
49
    }
49
    }
50
50
51
    public static MISignalEvent parse(
51
    public static MISignalEvent parse(
52
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
52
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
53
    {
53
    {
54
        String sigName = ""; //$NON-NLS-1$
54
        String sigName = ""; //$NON-NLS-1$
55
        String sigMeaning = ""; //$NON-NLS-1$
55
        String sigMeaning = ""; //$NON-NLS-1$
(-)src/org/eclipse/dd/mi/service/command/events/MIWatchpointTriggerEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 62-68 Link Here
62
    }
62
    }
63
63
64
    public static MIWatchpointTriggerEvent parse(
64
    public static MIWatchpointTriggerEvent parse(
65
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
65
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
66
    {
66
    {
67
        int number = 0;
67
        int number = 0;
68
        String exp = ""; //$NON-NLS-1$
68
        String exp = ""; //$NON-NLS-1$
(-)src/org/eclipse/dd/mi/service/command/events/MIStoppedEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 41-47 Link Here
41
    }
41
    }
42
42
43
    public static MIStoppedEvent parse(
43
    public static MIStoppedEvent parse(
44
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
44
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
45
    {
45
    {
46
	    int threadId = -1;
46
	    int threadId = -1;
47
	    MIFrame frame = null;
47
	    MIFrame frame = null;
(-)src/org/eclipse/dd/mi/service/command/events/MIFunctionFinishedEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 54-60 Link Here
54
    }
54
    }
55
55
56
    public static MIFunctionFinishedEvent parse(
56
    public static MIFunctionFinishedEvent parse(
57
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
57
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
58
    {
58
    {
59
        String gdbResult = ""; //$NON-NLS-1$
59
        String gdbResult = ""; //$NON-NLS-1$
60
        String returnValue = ""; //$NON-NLS-1$
60
        String returnValue = ""; //$NON-NLS-1$
(-)src/org/eclipse/dd/mi/service/command/events/MIWatchpointScopeEvent.java (-2 / +2 lines)
Lines 15-21 Link Here
15
import org.eclipse.dd.dsf.concurrent.Immutable;
15
import org.eclipse.dd.dsf.concurrent.Immutable;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
18
import org.eclipse.dd.mi.service.MIRunControl;
18
import org.eclipse.dd.mi.service.IMIRunControl;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
19
import org.eclipse.dd.mi.service.command.output.MIConst;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
20
import org.eclipse.dd.mi.service.command.output.MIFrame;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
21
import org.eclipse.dd.mi.service.command.output.MIResult;
Lines 42-48 Link Here
42
    }
42
    }
43
43
44
    public static MIWatchpointScopeEvent parse(
44
    public static MIWatchpointScopeEvent parse(
45
        MIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
45
        IMIRunControl runControl, IContainerDMContext containerDmc, int token, MIResult[] results) 
46
    {
46
    {
47
        int number = 0;
47
        int number = 0;
48
        for (int i = 0; i < results.length; i++) {
48
        for (int i = 0; i < results.length; i++) {
(-)src/org/eclipse/dd/mi/service/command/commands/MIVarCreate.java (-1 / +1 lines)
Lines 53-59 Link Here
53
        this(dmc, "-", "*", expression); //$NON-NLS-1$ //$NON-NLS-2$
53
        this(dmc, "-", "*", expression); //$NON-NLS-1$ //$NON-NLS-2$
54
    }
54
    }
55
55
56
    public MIVarCreate(IExpressionDMContext dmc,String name, String expression) {
56
    public MIVarCreate(IExpressionDMContext dmc, String name, String expression) {
57
        this(dmc, name, "*", expression); //$NON-NLS-1$
57
        this(dmc, name, "*", expression); //$NON-NLS-1$
58
    }
58
    }
59
59
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecStep.java (-2 / +16 lines)
Lines 14-24 Link Here
14
package org.eclipse.dd.mi.service.command.commands;
14
package org.eclipse.dd.mi.service.command.commands;
15
15
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
19
19
/**
20
/**
20
 * 
21
 * 
21
 *      -exec-step
22
 *      -exec-step [--thread <tid>] [count]
22
 *
23
 *
23
 *   Asynchronous command.  Resumes execution of the inferior program,
24
 *   Asynchronous command.  Resumes execution of the inferior program,
24
 * stopping when the beginning of the next source line is reached, if the
25
 * stopping when the beginning of the next source line is reached, if the
Lines 29-38 Link Here
29
public class MIExecStep extends MICommand<MIInfo> 
30
public class MIExecStep extends MICommand<MIInfo> 
30
{
31
{
31
    public MIExecStep(IExecutionDMContext dmc) {
32
    public MIExecStep(IExecutionDMContext dmc) {
32
        super(dmc, "-exec-step"); //$NON-NLS-1$
33
        this(dmc, 1);
33
    }
34
    }
34
35
35
    public MIExecStep(IExecutionDMContext dmc, int count) {
36
    public MIExecStep(IExecutionDMContext dmc, int count) {
36
        super(dmc, "-exec-step", new String[] { Integer.toString(count) }); //$NON-NLS-1$
37
        super(dmc, "-exec-step", new String[] { Integer.toString(count) }); //$NON-NLS-1$
37
    }
38
    }
39
40
    public MIExecStep(IMIExecutionDMContext dmc, boolean setThread) {
41
        this(dmc, setThread, 1);
42
    }
43
44
    public MIExecStep(IMIExecutionDMContext dmc, boolean setThread, int count) {
45
        super(dmc, "-exec-step");	//$NON-NLS-1$
46
        if (setThread) {
47
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$
48
        } else {
49
        	setParameters(new String[] { Integer.toString(count) });
50
        }
51
    }
38
}
52
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecInterrupt.java (-1 / +16 lines)
Lines 14-24 Link Here
14
package org.eclipse.dd.mi.service.command.commands;
14
package org.eclipse.dd.mi.service.command.commands;
15
15
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
19
19
/**
20
/**
20
 * 
21
 * 
21
 *      -exec-interrupt
22
 *      -exec-interrupt [ --thread <tid> | --all ]
22
 *
23
 *
23
 *  Asynchronous command.  Interrupts the background execution of the
24
 *  Asynchronous command.  Interrupts the background execution of the
24
 *  target.  Note how the token associated with the stop message is the one
25
 *  target.  Note how the token associated with the stop message is the one
Lines 31-36 Link Here
31
public class MIExecInterrupt extends MICommand<MIInfo> 
32
public class MIExecInterrupt extends MICommand<MIInfo> 
32
{
33
{
33
    public MIExecInterrupt(IExecutionDMContext dmc) {
34
    public MIExecInterrupt(IExecutionDMContext dmc) {
35
        this(dmc, false);
36
    }
37
38
    public MIExecInterrupt(IExecutionDMContext dmc, boolean allThreads) {
39
        super(dmc, "-exec-interrupt"); //$NON-NLS-1$
40
        if (allThreads) {
41
        	setParameters(new String[] { "--all" }); //$NON-NLS-1$
42
        }
43
    }
44
45
    public MIExecInterrupt(IMIExecutionDMContext dmc, boolean setThread) {
34
        super(dmc, "-exec-interrupt"); //$NON-NLS-1$
46
        super(dmc, "-exec-interrupt"); //$NON-NLS-1$
47
        if (setThread) {
48
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()) }); //$NON-NLS-1$
49
        }
35
    }
50
    }
36
}
51
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecNextInstruction.java (-1 / +15 lines)
Lines 13-18 Link Here
13
package org.eclipse.dd.mi.service.command.commands;
13
package org.eclipse.dd.mi.service.command.commands;
14
14
15
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
15
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
16
import org.eclipse.dd.mi.service.command.output.MIInfo;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
17
18
18
/**
19
/**
Lines 28-37 Link Here
28
public class MIExecNextInstruction extends MICommand<MIInfo> 
29
public class MIExecNextInstruction extends MICommand<MIInfo> 
29
{
30
{
30
    public MIExecNextInstruction(IExecutionDMContext dmc) {
31
    public MIExecNextInstruction(IExecutionDMContext dmc) {
31
        super(dmc, "-exec-next-instruction"); //$NON-NLS-1$
32
        this(dmc, 1);
32
    }
33
    }
33
34
34
    public MIExecNextInstruction(IExecutionDMContext dmc, int count) {
35
    public MIExecNextInstruction(IExecutionDMContext dmc, int count) {
35
        super(dmc, "-exec-next-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$
36
        super(dmc, "-exec-next-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$
36
    }
37
    }
38
39
    public MIExecNextInstruction(IMIExecutionDMContext dmc, boolean setThread) {
40
        this(dmc, setThread, 1);
41
    }
42
43
    public MIExecNextInstruction(IMIExecutionDMContext dmc, boolean setThread, int count) {
44
        super(dmc, "-exec-next-instruction");	//$NON-NLS-1$
45
        if (setThread) {
46
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$
47
        } else {
48
        	setParameters(new String[] { Integer.toString(count) });
49
        }
50
    }
37
}
51
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecStepInstruction.java (-2 / +16 lines)
Lines 13-23 Link Here
13
package org.eclipse.dd.mi.service.command.commands;
13
package org.eclipse.dd.mi.service.command.commands;
14
14
15
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
15
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
16
import org.eclipse.dd.mi.service.command.output.MIInfo;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
17
18
18
/**
19
/**
19
 * 
20
 * 
20
 *      -exec-step-instruction
21
 *      -exec-step-instruction [--thread <tid>] [count]
21
22
22
 *  Asynchronous command.  Resumes the inferior which executes one
23
 *  Asynchronous command.  Resumes the inferior which executes one
23
 * machine instruction.  The output, once GDB has stopped, will vary
24
 * machine instruction.  The output, once GDB has stopped, will vary
Lines 29-38 Link Here
29
public class MIExecStepInstruction extends MICommand<MIInfo> 
30
public class MIExecStepInstruction extends MICommand<MIInfo> 
30
{
31
{
31
    public MIExecStepInstruction(IExecutionDMContext dmc) {
32
    public MIExecStepInstruction(IExecutionDMContext dmc) {
32
        super(dmc, "-exec-step-instruction"); //$NON-NLS-1$
33
        this(dmc, 1);
33
    }
34
    }
34
35
35
    public MIExecStepInstruction(IExecutionDMContext dmc, int count) {
36
    public MIExecStepInstruction(IExecutionDMContext dmc, int count) {
36
        super(dmc, "-exec-step-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$
37
        super(dmc, "-exec-step-instruction", new String[] { Integer.toString(count) }); //$NON-NLS-1$
37
    }
38
    }
39
40
    public MIExecStepInstruction(IMIExecutionDMContext dmc, boolean setThread) {
41
        this(dmc, setThread, 1);
42
    }
43
44
    public MIExecStepInstruction(IMIExecutionDMContext dmc, boolean setThread, int count) {
45
        super(dmc, "-exec-step-instruction");	//$NON-NLS-1$
46
        if (setThread) {
47
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$
48
        } else {
49
        	setParameters(new String[] { Integer.toString(count) });
50
        }
51
    }
38
}
52
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecReturn.java (-2 / +1 lines)
Lines 17-23 Link Here
17
17
18
/**
18
/**
19
 * 
19
 * 
20
 *  <code>-exec-return</code>
20
 *  -exec-return [args]
21
 *
21
 *
22
 *  <p>
22
 *  <p>
23
 *  Makes current function return immediately.  Doesn't execute the
23
 *  Makes current function return immediately.  Doesn't execute the
Lines 38-42 Link Here
38
    public MIExecReturn(IFrameDMContext dmc, String arg) {
38
    public MIExecReturn(IFrameDMContext dmc, String arg) {
39
        super(dmc, "-exec-return", new String[] { arg }); //$NON-NLS-1$
39
        super(dmc, "-exec-return", new String[] { arg }); //$NON-NLS-1$
40
    }
40
    }
41
42
}
41
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecUntil.java (-2 / +19 lines)
Lines 14-24 Link Here
14
package org.eclipse.dd.mi.service.command.commands;
14
package org.eclipse.dd.mi.service.command.commands;
15
15
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
19
19
/**
20
/**
20
 * 
21
 * 
21
 *     -exec-until [ LOCATION ]
22
 *     -exec-until [--thread <tid>] [ LOCATION ]
22
 *
23
 *
23
 *  Asynchronous command.  Executes the inferior until the LOCATION
24
 *  Asynchronous command.  Executes the inferior until the LOCATION
24
 * specified in the argument is reached.  If there is no argument, the
25
 * specified in the argument is reached.  If there is no argument, the
Lines 34-39 Link Here
34
    }
35
    }
35
36
36
    public MIExecUntil(IExecutionDMContext dmc, String loc) {
37
    public MIExecUntil(IExecutionDMContext dmc, String loc) {
37
        super(dmc, "-exec-until", new String[]{loc}); //$NON-NLS-1$
38
        super(dmc, "-exec-until", new String[] { loc }); //$NON-NLS-1$
39
    }
40
41
    public MIExecUntil(IMIExecutionDMContext dmc, boolean setThread) {
42
        super(dmc, "-exec-until"); //$NON-NLS-1$
43
        if (setThread) {
44
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()) }); //$NON-NLS-1$
45
        }
46
    }
47
48
    public MIExecUntil(IMIExecutionDMContext dmc, boolean setThread, String loc) {
49
        super(dmc, "-exec-until"); //$NON-NLS-1$
50
        if (setThread) {
51
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), loc }); //$NON-NLS-1$
52
        } else {
53
        	setParameters(new String[] { loc });
54
        }
38
    }
55
    }
39
}
56
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackListLocals.java (-6 / +13 lines)
Lines 13-19 Link Here
13
13
14
package org.eclipse.dd.mi.service.command.commands;
14
package org.eclipse.dd.mi.service.command.commands;
15
15
16
import org.eclipse.dd.dsf.datamodel.DMContexts;
16
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
17
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
18
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIOutput;
19
import org.eclipse.dd.mi.service.command.output.MIOutput;
18
import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo;
20
import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo;
19
21
Lines 30-41 Link Here
30
{
32
{
31
	
33
	
32
    public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) {
34
    public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) {
33
        super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$
35
        this(frameCtx, false, printValues);
34
        if (printValues) {
36
    }
35
            setParameters(new String[]{"1"}); //$NON-NLS-1$
37
36
        } else {
38
    public MIStackListLocals(IFrameDMContext frameCtx, boolean setThread, boolean printValues) {
37
            setParameters(new String[]{"0"}); //$NON-NLS-1$
39
      super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$
38
        }
40
      IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameCtx, IMIExecutionDMContext.class);
41
      if (setThread && execDmc != null) {
42
      	 setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), printValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
43
      } else {
44
      	 setParameters(new String[] { printValues ? "1" : "0" } );  //$NON-NLS-1$ //$NON-NLS-2$
45
      }
39
    }
46
    }
40
    
47
    
41
    @Override
48
    @Override
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecNext.java (-8 / +22 lines)
Lines 14-24 Link Here
14
package org.eclipse.dd.mi.service.command.commands;
14
package org.eclipse.dd.mi.service.command.commands;
15
15
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
16
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
17
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
17
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
import org.eclipse.dd.mi.service.command.output.MIInfo;
18
19
19
/**
20
/**
20
 * 
21
 * 
21
 *     -exec-next
22
 *     -exec-next [--thread <tid>] [count]
22
 *
23
 *
23
 *  Asynchronous command.  Resumes execution of the inferior program,
24
 *  Asynchronous command.  Resumes execution of the inferior program,
24
 *  stopping when the beginning of the next source line is reached.
25
 *  stopping when the beginning of the next source line is reached.
Lines 26-36 Link Here
26
 */
27
 */
27
public class MIExecNext extends MICommand<MIInfo> 
28
public class MIExecNext extends MICommand<MIInfo> 
28
{
29
{
29
    public MIExecNext(IExecutionDMContext dmc) {
30
	public MIExecNext(IExecutionDMContext dmc) {
30
        super(dmc, "-exec-next"); //$NON-NLS-1$
31
	    this(dmc, 1);
31
    }
32
	}
32
33
33
    public MIExecNext(IExecutionDMContext dmc, int count) {
34
	public MIExecNext(IExecutionDMContext dmc, int count) {
34
        super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$
35
	    super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$
35
    }
36
	}
36
}
37
38
	public MIExecNext(IMIExecutionDMContext dmc, boolean setThread) {
39
	    this(dmc, setThread, 1);
40
	}
41
42
	public MIExecNext(IMIExecutionDMContext dmc, boolean setThread, int count) {
43
	    super(dmc, "-exec-next");	//$NON-NLS-1$
44
	    if (setThread) {
45
	    	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()), Integer.toString(count) }); //$NON-NLS-1$
46
	    } else {
47
	    	setParameters(new String[] { Integer.toString(count) });
48
	    }
49
	}
50
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackInfoDepth.java (-2 / +19 lines)
Lines 17-23 Link Here
17
17
18
/**
18
/**
19
 * 
19
 * 
20
 *     -stack-info-depth [maxDepth]
20
 *     -stack-info-depth [--thread <tid>] [maxDepth]
21
 *
21
 *
22
 * 
22
 * 
23
 */
23
 */
Lines 25-37 Link Here
25
{
25
{
26
	
26
	
27
    public MIStackInfoDepth(IMIExecutionDMContext ctx) {
27
    public MIStackInfoDepth(IMIExecutionDMContext ctx) {
28
    	this(ctx, false);
29
    }    	
30
31
    public MIStackInfoDepth(IMIExecutionDMContext ctx, boolean setThread) {
28
    	super(ctx, "-stack-info-depth"); //$NON-NLS-1$
32
    	super(ctx, "-stack-info-depth"); //$NON-NLS-1$
33
    	if (setThread) {
34
    		setParameters(new String[] { "--thread", Integer.toString(ctx.getThreadId()) }); //$NON-NLS-1$
35
    	}
29
    }    	
36
    }    	
30
37
31
    public MIStackInfoDepth(IMIExecutionDMContext ctx, int maxDepth) {
38
    public MIStackInfoDepth(IMIExecutionDMContext ctx, int maxDepth) {
32
        super(ctx, "-stack-info-depth", new String[]{Integer.toString(maxDepth)}); //$NON-NLS-1$
39
        this(ctx, false, maxDepth);
33
    }
40
    }
34
    
41
    
42
    public MIStackInfoDepth(IMIExecutionDMContext ctx, boolean setThread, int maxDepth) {
43
        super(ctx, "-stack-info-depth"); //$NON-NLS-1$
44
        if (setThread) {
45
        	setParameters(new String[] { "--thread", Integer.toString(ctx.getThreadId()), Integer.toString(maxDepth) }); //$NON-NLS-1$
46
        }
47
        else {
48
        	setParameters(new String[] { Integer.toString(maxDepth) });
49
        }
50
    }
51
35
    @Override
52
    @Override
36
    public MIStackInfoDepthInfo getResult(MIOutput out) {
53
    public MIStackInfoDepthInfo getResult(MIOutput out) {
37
        return new MIStackInfoDepthInfo(out);
54
        return new MIStackInfoDepthInfo(out);
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackSelectFrame.java (-2 / +4 lines)
Lines 15-22 Link Here
15
import org.eclipse.dd.dsf.datamodel.IDMContext;
15
import org.eclipse.dd.dsf.datamodel.IDMContext;
16
import org.eclipse.dd.mi.service.command.output.MIInfo;
16
import org.eclipse.dd.mi.service.command.output.MIInfo;
17
17
18
19
20
/**
18
/**
21
 * 
19
 * 
22
 *     -stack-select-frame FRAMENUM
20
 *     -stack-select-frame FRAMENUM
Lines 30-33 Link Here
30
	public MIStackSelectFrame(IDMContext ctx, int frameNum) {
28
	public MIStackSelectFrame(IDMContext ctx, int frameNum) {
31
		super(ctx, "-stack-select-frame", new String[]{Integer.toString(frameNum)}, new String[0]); //$NON-NLS-1$
29
		super(ctx, "-stack-select-frame", new String[]{Integer.toString(frameNum)}, new String[0]); //$NON-NLS-1$
32
	}
30
	}
31
	
32
	public MIStackSelectFrame(IDMContext ctx, int threadNum, int frameNum) {
33
		super(ctx, "-stack-select-frame", new String[]{ "--thread", Integer.toString(threadNum), Integer.toString(frameNum) }); //$NON-NLS-1$ //$NON-NLS-2$
34
	}
33
}
35
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackListArguments.java (-17 / +18 lines)
Lines 20-26 Link Here
20
20
21
/**
21
/**
22
 * 
22
 * 
23
 *    -stack-list-arguments SHOW-VALUES
23
 *    -stack-list-arguments [--thread <tid>] SHOW-VALUES
24
 *        [ LOW-FRAME HIGH-FRAME ]
24
 *        [ LOW-FRAME HIGH-FRAME ]
25
 *
25
 *
26
 *  Display a list of the arguments for the frames between LOW-FRAME and
26
 *  Display a list of the arguments for the frames between LOW-FRAME and
Lines 35-68 Link Here
35
public class MIStackListArguments extends MICommand<MIStackListArgumentsInfo> 
35
public class MIStackListArguments extends MICommand<MIStackListArgumentsInfo> 
36
{
36
{
37
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues) {
37
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues) {
38
        this(execDmc, false, showValues);
39
    }
40
41
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean setThread, boolean showValues) {
38
        super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$
42
        super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$
39
        if (showValues) {
43
        if (setThread) {
40
            setParameters(new String[]{"1"}); //$NON-NLS-1$
44
        	setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), showValues ? "1" : "0" } ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
41
        } else {
45
        } else {
42
            setParameters(new String[]{"0"}); //$NON-NLS-1$
46
        	setParameters(new String[] { showValues ? "1" : "0" } );  //$NON-NLS-1$ //$NON-NLS-2$
43
        }
47
        }
44
    }
48
    }
45
49
46
    public MIStackListArguments(IFrameDMContext frameDmc, boolean showValues) {
50
    public MIStackListArguments(IFrameDMContext frameDmc, boolean showValues) {
47
        super(frameDmc, "-stack-list-arguments"); //$NON-NLS-1$
51
        super(frameDmc, "-stack-list-arguments", new String[] { showValues ? "1" : "0" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
48
        if (showValues) {
49
            setParameters(new String[]{"1"}); //$NON-NLS-1$
50
        } else {
51
            setParameters(new String[]{"0"}); //$NON-NLS-1$
52
        }
53
    }
52
    }
54
    
53
    
55
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues, int low, int high) {
54
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean showValues, int low, int high) {
55
        this(execDmc, false, showValues, low, high);
56
    }
57
    
58
    public MIStackListArguments(IMIExecutionDMContext execDmc, boolean setThread, boolean showValues, int low, int high) {
56
        super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$
59
        super(execDmc, "-stack-list-arguments"); //$NON-NLS-1$
57
        String[] params = new String[3];
60
        if (setThread) {
58
        if (showValues) {
61
        	setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()),  //$NON-NLS-1$
59
            params[0] = "1"; //$NON-NLS-1$
62
        			showValues ? "1" : "0", Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$ //$NON-NLS-2$
60
        } else {
63
        } else {
61
            params[0] = "0"; //$NON-NLS-1$
64
        	setParameters(new String[] {
65
        			showValues ? "1" : "0", Integer.toString(low), Integer.toString(high) } );  //$NON-NLS-1$ //$NON-NLS-2$
62
        }
66
        }
63
        params[1] = Integer.toString(low);
64
        params[2] = Integer.toString(high);
65
        setParameters(params);
66
    }
67
    }
67
    
68
    
68
    @Override
69
    @Override
(-)src/org/eclipse/dd/mi/service/command/commands/MIExecContinue.java (-1 / +12 lines)
Lines 17-23 Link Here
17
17
18
/**
18
/**
19
 * 
19
 * 
20
 *      -exec-continue
20
 *      -exec-continue [--thread <tid>]
21
 * 
21
 * 
22
 *   Asynchronous command.  Resumes the execution of the inferior program
22
 *   Asynchronous command.  Resumes the execution of the inferior program
23
 *   until a breakpoint is encountered, or until the inferior exits.
23
 *   until a breakpoint is encountered, or until the inferior exits.
Lines 26-31 Link Here
26
public class MIExecContinue extends MICommand<MIInfo> 
26
public class MIExecContinue extends MICommand<MIInfo> 
27
{
27
{
28
    public MIExecContinue(IExecutionDMContext dmc) {
28
    public MIExecContinue(IExecutionDMContext dmc) {
29
        this(dmc, false);
30
    }
31
32
    public MIExecContinue(IExecutionDMContext dmc, boolean allThreads) {
29
        super(dmc, "-exec-continue"); //$NON-NLS-1$
33
        super(dmc, "-exec-continue"); //$NON-NLS-1$
34
        if (allThreads) {
35
        	setParameters(new String[] { "--all" }); //$NON-NLS-1$
36
        }
37
    }
38
39
    public MIExecContinue(IExecutionDMContext dmc, int threadId) {
40
        super(dmc, "-exec-continue", new String[] { "--thread", Integer.toString(threadId) }); //$NON-NLS-1$ //$NON-NLS-2$
30
    }
41
    }
31
}
42
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java (-2 / +17 lines)
Lines 54-65 Link Here
54
public class MIStackListFrames extends MICommand<MIStackListFramesInfo>
54
public class MIStackListFrames extends MICommand<MIStackListFramesInfo>
55
{
55
{
56
    public MIStackListFrames(IMIExecutionDMContext execDmc) {
56
    public MIStackListFrames(IMIExecutionDMContext execDmc) {
57
        this(execDmc, false);
58
    }
59
    
60
    public MIStackListFrames(IMIExecutionDMContext execDmc, boolean setThread) {
57
        super(execDmc, "-stack-list-frames"); //$NON-NLS-1$
61
        super(execDmc, "-stack-list-frames"); //$NON-NLS-1$
62
        if (setThread) {
63
        	setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()) } ); //$NON-NLS-1$
64
        }
58
    }
65
    }
59
    
66
    
60
    public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) {
67
    public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) {
61
        super(execDmc, "-stack-list-frames", new String[]{Integer.toString(low), //$NON-NLS-1$
68
        this(execDmc, false, low, high);
62
        										 Integer.toString(high)});
69
    }
70
    
71
    public MIStackListFrames(IMIExecutionDMContext execDmc, boolean setThread, int low, int high) {
72
        super(execDmc, "-stack-list-frames"); //$NON-NLS-1$
73
        if (setThread) {
74
        	setParameters(new String[] { "--thread", Integer.toString(execDmc.getThreadId()), Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$
75
        } else {
76
        	setParameters(new String[] { Integer.toString(low), Integer.toString(high) } );
77
        }
63
    }
78
    }
64
    
79
    
65
    @Override
80
    @Override
(-)src/org/eclipse/dd/mi/service/MIBreakpointsManager.java (-3 / +2 lines)
Lines 71-77 Link Here
71
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent;
71
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent;
72
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent;
72
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent;
73
import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext;
73
import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext;
74
import org.eclipse.dd.mi.service.MIRunControl.MIExecutionDMC;
75
import org.eclipse.dd.mi.service.breakpoint.actions.BreakpointActionAdapter;
74
import org.eclipse.dd.mi.service.breakpoint.actions.BreakpointActionAdapter;
76
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
75
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
77
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
76
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
Lines 1516-1523 Link Here
1516
        Set<String> results = new HashSet<String>();
1515
        Set<String> results = new HashSet<String>();
1517
        if ((threads != null) && (supportsThreads(breakpoint))) {
1516
        if ((threads != null) && (supportsThreads(breakpoint))) {
1518
            for (IExecutionDMContext thread : threads) {
1517
            for (IExecutionDMContext thread : threads) {
1519
                if (thread instanceof MIExecutionDMC) {
1518
                if (thread instanceof IMIExecutionDMContext) {
1520
                    MIExecutionDMC dmc = (MIExecutionDMC) thread;
1519
                	IMIExecutionDMContext dmc = (IMIExecutionDMContext) thread;
1521
                    results.add(((Integer) dmc.getThreadId()).toString());
1520
                    results.add(((Integer) dmc.getThreadId()).toString());
1522
                }
1521
                }
1523
            }
1522
            }
(-)src/org/eclipse/dd/mi/service/MIMemory.java (-7 / +2 lines)
Lines 69-76 Link Here
69
        }
69
        }
70
    }
70
    }
71
71
72
    @SuppressWarnings("unused")
73
	private MIRunControl fRunControl;
74
    private MIMemoryCache fMemoryCache;
72
    private MIMemoryCache fMemoryCache;
75
73
76
	/**
74
	/**
Lines 113-121 Link Here
113
    	// Register this service
111
    	// Register this service
114
    	register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
112
    	register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
115
113
116
    	// Get the RunControl so we can retrieve the current Execution context
117
    	fRunControl = getServicesTracker().getService(MIRunControl.class);
118
119
    	// Create the memory requests cache
114
    	// Create the memory requests cache
120
    	fMemoryCache = new MIMemoryCache();
115
    	fMemoryCache = new MIMemoryCache();
121
116
Lines 279-285 Link Here
279
    //////////////////////////////////////////////////////////////////////////
274
    //////////////////////////////////////////////////////////////////////////
280
275
281
    @DsfServiceEventHandler
276
    @DsfServiceEventHandler
282
	public void eventDispatched(IRunControl.IResumedDMEvent e) {
277
	public void eventDispatched(IRunControl.IContainerResumedDMEvent e) {
283
		fMemoryCache.setTargetAvailable(e.getDMContext(), false);
278
		fMemoryCache.setTargetAvailable(e.getDMContext(), false);
284
		if (e.getReason() != StateChangeReason.STEP) {
279
		if (e.getReason() != StateChangeReason.STEP) {
285
			fMemoryCache.reset();
280
			fMemoryCache.reset();
Lines 287-293 Link Here
287
	}
282
	}
288
   
283
   
289
    @DsfServiceEventHandler
284
    @DsfServiceEventHandler
290
	public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
285
	public void eventDispatched(IRunControl.IContainerSuspendedDMEvent e) {
291
		fMemoryCache.setTargetAvailable(e.getDMContext(), true);
286
		fMemoryCache.setTargetAvailable(e.getDMContext(), true);
292
		fMemoryCache.reset();
287
		fMemoryCache.reset();
293
	}
288
	}
(-)src/org/eclipse/dd/mi/service/ExpressionService.java (-1 lines)
Lines 893-899 Link Here
893
		}
893
		}
894
	}
894
	}
895
895
896
897
    @DsfServiceEventHandler 
896
    @DsfServiceEventHandler 
898
    public void eventDispatched(IRunControl.IResumedDMEvent e) {
897
    public void eventDispatched(IRunControl.IResumedDMEvent e) {
899
        fExpressionCache.setContextAvailable(e.getDMContext(), false);
898
        fExpressionCache.setContextAvailable(e.getDMContext(), false);
(-)src/org/eclipse/dd/mi/service/MIRunControl.java (-188 / +199 lines)
Lines 21-27 Link Here
21
import org.eclipse.dd.dsf.datamodel.DMContexts;
21
import org.eclipse.dd.dsf.datamodel.DMContexts;
22
import org.eclipse.dd.dsf.datamodel.IDMContext;
22
import org.eclipse.dd.dsf.datamodel.IDMContext;
23
import org.eclipse.dd.dsf.datamodel.IDMEvent;
23
import org.eclipse.dd.dsf.datamodel.IDMEvent;
24
import org.eclipse.dd.dsf.debug.service.IRunControl;
25
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
24
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
26
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
25
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
27
import org.eclipse.dd.dsf.service.AbstractDsfService;
26
import org.eclipse.dd.dsf.service.AbstractDsfService;
Lines 71-267 Link Here
71
 * events and track service state, to be perfectly in sync with the service
70
 * events and track service state, to be perfectly in sync with the service
72
 * state.
71
 * state.
73
 */
72
 */
74
public class MIRunControl extends AbstractDsfService implements IRunControl
73
public class MIRunControl extends AbstractDsfService implements IMIRunControl
75
{
74
{
76
    protected class MIExecutionDMC extends AbstractDMContext
75
	class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext
77
        implements IMIExecutionDMContext
76
	{
78
    {
77
		/**
79
        /**
78
		 * Integer ID that is used to identify the thread in the GDB/MI protocol.
80
         * Integer ID that is used to identify the thread in the GDB/MI protocol.
79
		 */
81
         */
80
		private final int fThreadId;
82
        private final int fThreadId;
81
83
    
82
		/**
84
        /**
83
		 * Constructor for the context.  It should not be called directly by clients.
85
         * Constructor for the context.  It should not be called directly by clients.
84
		 * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)}
86
         * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)}
85
		 * to create instances of this context based on the thread ID.
87
         * to create instances of this context based on the thread ID.
86
		 * <p/>
88
         * <p/>
87
		 * Classes extending {@link MIRunControl} may also extend this class to include
89
         * Classes extending {@link MIRunControl} may also extend this class to include
88
		 * additional information in the context.
90
         * additional information in the context.
89
		 * 
91
         * 
90
		 * @param sessionId Session that this context belongs to.
92
         * @param sessionId Session that this context belongs to.
91
		 * @param containerDmc The container that this context belongs to.
93
         * @param containerDmc The container that this context belongs to.
92
		 * @param threadId GDB/MI thread identifier.
94
         * @param threadId GDB/MI thread identifier.
93
		 */
95
         */
94
		protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) {
96
        protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) {
95
			super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
97
            super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
96
			fThreadId = threadId;
98
            fThreadId = threadId;
97
		}
99
        }
100
    
101
        /**
102
         * Returns the GDB/MI thread identifier of this context.
103
         * @return
104
         */
105
        public int getThreadId(){
106
            return fThreadId;
107
        }
108
        
109
        @Override
110
        public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; }  //$NON-NLS-1$ //$NON-NLS-2$
111
    
112
        @Override
113
        public boolean equals(Object obj) {
114
            return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId;
115
        }
116
        
117
        @Override
118
        public int hashCode() { return super.baseHashCode() ^ fThreadId; }
119
    }
120
    
121
    @Immutable
122
    private static class ExecutionData implements IExecutionDMData {
123
        private final StateChangeReason fReason;
124
        ExecutionData(StateChangeReason reason) {
125
            fReason = reason;
126
        }
127
        public StateChangeReason getStateChangeReason() { return fReason; }
128
    }
129
98
130
    /**
99
		/**
131
     * Base class for events generated by the MI Run Control service.  Most events
100
		 * Returns the GDB/MI thread identifier of this context.
132
     * generated by the MI Run Control service are directly caused by some MI event.
101
		 * @return
133
     * Other services may need access to the extended MI data carried in the event.
102
		 */
134
     * 
103
		public int getThreadId(){
135
     * @param <V> DMC that this event refers to
104
			return fThreadId;
136
     * @param <T> MIInfo object that is the direct cause of this event
105
		}
137
     * @see MIRunControl
138
     */
139
    @Immutable
140
    protected static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V>
141
        implements IDMEvent<V>, IMIDMEvent
142
    {
143
        final private T fMIInfo;
144
        public RunControlEvent(V dmc, T miInfo) {
145
            super(dmc);
146
            fMIInfo = miInfo;
147
        }
148
        
149
        public T getMIEvent() { return fMIInfo; }
150
    }
151
    
152
    /**
153
     * Indicates that the given thread has been suspended.
154
     */
155
    @Immutable
156
    protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
157
        implements ISuspendedDMEvent
158
    {
159
        SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
160
            super(ctx, miInfo);
161
        }
162
        
163
        public StateChangeReason getReason() {
164
            if (getMIEvent() instanceof MIBreakpointHitEvent) {
165
                return StateChangeReason.BREAKPOINT;
166
            } else if (getMIEvent() instanceof MISteppingRangeEvent) {
167
                return StateChangeReason.STEP;
168
            } else if (getMIEvent() instanceof MISharedLibEvent) {
169
                return StateChangeReason.SHAREDLIB;
170
            }else if (getMIEvent() instanceof MISignalEvent) {
171
                return StateChangeReason.SIGNAL;
172
            }else if (getMIEvent() instanceof MIWatchpointTriggerEvent) {
173
                return StateChangeReason.WATCHPOINT;
174
            }else if (getMIEvent() instanceof MIErrorEvent) {
175
                return StateChangeReason.ERROR;
176
            }else {
177
                return StateChangeReason.USER_REQUEST;
178
            }
179
        }
180
    }
181
106
182
    @Immutable
107
		@Override
183
    protected static class ContainerSuspendedEvent extends SuspendedEvent
108
		public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; }  //$NON-NLS-1$ //$NON-NLS-2$
184
        implements IContainerSuspendedDMEvent
185
    {
186
        final IExecutionDMContext[] triggeringDmcs;
187
        ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
188
            super(containerDmc, miInfo);
189
            this.triggeringDmcs = triggeringDmc != null
190
                ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
191
        }
192
        
193
        public IExecutionDMContext[] getTriggeringContexts() {
194
            return triggeringDmcs;
195
        }
196
    }
197
109
198
    @Immutable
110
		@Override
199
    protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
111
		public boolean equals(Object obj) {
200
        implements IResumedDMEvent
112
			return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId;
201
    {
113
		}
202
        ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
203
            super(ctx, miInfo);
204
        }
205
        
206
        public StateChangeReason getReason() {
207
            switch(getMIEvent().getType()) {
208
                case MIRunningEvent.CONTINUE:
209
                    return StateChangeReason.USER_REQUEST;
210
                case MIRunningEvent.NEXT:
211
                case MIRunningEvent.NEXTI:
212
                    return StateChangeReason.STEP;
213
                case MIRunningEvent.STEP:
214
                case MIRunningEvent.STEPI:
215
                    return StateChangeReason.STEP;
216
                case MIRunningEvent.FINISH:
217
                    return StateChangeReason.STEP;
218
                case MIRunningEvent.UNTIL:
219
                case MIRunningEvent.RETURN:
220
                    break;
221
            }
222
            return StateChangeReason.UNKNOWN;
223
        }
224
    }
225
114
226
    @Immutable
115
		@Override
227
    protected static class ContainerResumedEvent extends ResumedEvent
116
		public int hashCode() { return super.baseHashCode() ^ fThreadId; }
228
        implements IContainerResumedDMEvent
117
	}
229
    {
118
230
        final IExecutionDMContext[] triggeringDmcs;
119
	@Immutable
231
120
	static class ExecutionData implements IExecutionDMData {
232
        ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
121
		private final StateChangeReason fReason;
233
            super(containerDmc, miInfo);
122
		ExecutionData(StateChangeReason reason) {
234
            this.triggeringDmcs = triggeringDmc != null
123
			fReason = reason;
235
                ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
124
		}
236
        }
125
		public StateChangeReason getStateChangeReason() { return fReason; }
237
        
126
	}
238
        public IExecutionDMContext[] getTriggeringContexts() {
127
239
            return triggeringDmcs;
128
	/**
240
        }
129
	 * Base class for events generated by the MI Run Control service.  Most events
241
    }
130
	 * generated by the MI Run Control service are directly caused by some MI event.
242
    
131
	 * Other services may need access to the extended MI data carried in the event.
243
    @Immutable
132
	 * 
244
    protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
133
	 * @param <V> DMC that this event refers to
245
        implements IStartedDMEvent
134
	 * @param <T> MIInfo object that is the direct cause of this event
246
    {
135
	 * @see MIRunControl
247
        StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
136
	 */
248
            super(executionDmc, miInfo);
137
	@Immutable
249
        }
138
	static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V>
250
    }
139
	implements IDMEvent<V>, IMIDMEvent
251
    
140
	{
252
    @Immutable
141
		final private T fMIInfo;
253
    protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
142
		public RunControlEvent(V dmc, T miInfo) {
254
        implements IExitedDMEvent
143
			super(dmc);
255
    {
144
			fMIInfo = miInfo;
256
        ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
145
		}
257
            super(executionDmc, miInfo);
146
258
        }
147
		public T getMIEvent() { return fMIInfo; }
259
    }
148
	}
260
    
149
261
    private AbstractMIControl   fConnection;
150
	/**
151
	 * Indicates that the given thread has been suspended.
152
	 */
153
	@Immutable
154
	static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
155
	implements ISuspendedDMEvent
156
	{
157
		SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
158
			super(ctx, miInfo);
159
		}
160
161
		public StateChangeReason getReason() {
162
			if (getMIEvent() instanceof MIBreakpointHitEvent) {
163
				return StateChangeReason.BREAKPOINT;
164
			} else if (getMIEvent() instanceof MISteppingRangeEvent) {
165
				return StateChangeReason.STEP;
166
			} else if (getMIEvent() instanceof MISharedLibEvent) {
167
				return StateChangeReason.SHAREDLIB;
168
			}else if (getMIEvent() instanceof MISignalEvent) {
169
				return StateChangeReason.SIGNAL;
170
			}else if (getMIEvent() instanceof MIWatchpointTriggerEvent) {
171
				return StateChangeReason.WATCHPOINT;
172
			}else if (getMIEvent() instanceof MIErrorEvent) {
173
				return StateChangeReason.ERROR;
174
			}else {
175
				return StateChangeReason.USER_REQUEST;
176
			}
177
		}
178
	}
179
180
	@Immutable
181
	static class ContainerSuspendedEvent extends SuspendedEvent
182
	implements IContainerSuspendedDMEvent
183
	{
184
		final IExecutionDMContext[] triggeringDmcs;
185
		ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
186
			super(containerDmc, miInfo);
187
			this.triggeringDmcs = triggeringDmc != null
188
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
189
		}
190
191
		public IExecutionDMContext[] getTriggeringContexts() {
192
			return triggeringDmcs;
193
		}
194
	}
195
196
	@Immutable
197
	static class ThreadSuspendedEvent extends SuspendedEvent
198
	{
199
		ThreadSuspendedEvent(IExecutionDMContext executionDmc, MIStoppedEvent miInfo) {
200
			super(executionDmc, miInfo);
201
		}
202
	}
203
204
	@Immutable
205
	static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
206
	implements IResumedDMEvent
207
	{
208
		ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
209
			super(ctx, miInfo);
210
		}
211
212
		public StateChangeReason getReason() {
213
			switch(getMIEvent().getType()) {
214
			case MIRunningEvent.CONTINUE:
215
				return StateChangeReason.USER_REQUEST;
216
			case MIRunningEvent.NEXT:
217
			case MIRunningEvent.NEXTI:
218
				return StateChangeReason.STEP;
219
			case MIRunningEvent.STEP:
220
			case MIRunningEvent.STEPI:
221
				return StateChangeReason.STEP;
222
			case MIRunningEvent.FINISH:
223
				return StateChangeReason.STEP;
224
			case MIRunningEvent.UNTIL:
225
			case MIRunningEvent.RETURN:
226
				break;
227
			}
228
			return StateChangeReason.UNKNOWN;
229
		}
230
	}
231
232
	@Immutable
233
	static class ContainerResumedEvent extends ResumedEvent
234
	implements IContainerResumedDMEvent
235
	{
236
		final IExecutionDMContext[] triggeringDmcs;
237
238
		ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
239
			super(containerDmc, miInfo);
240
			this.triggeringDmcs = triggeringDmc != null
241
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
242
		}
243
244
		public IExecutionDMContext[] getTriggeringContexts() {
245
			return triggeringDmcs;
246
		}
247
	}
248
249
	@Immutable
250
	static class ThreadResumedEvent extends ResumedEvent
251
	{
252
		ThreadResumedEvent(IExecutionDMContext executionDmc, MIRunningEvent miInfo) {
253
			super(executionDmc, miInfo);
254
		}
255
	}
256
257
	@Immutable
258
	static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
259
	implements IStartedDMEvent
260
	{
261
		StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
262
			super(executionDmc, miInfo);
263
		}
264
	}
265
266
	@Immutable
267
	static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
268
	implements IExitedDMEvent
269
	{
270
		ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
271
			super(executionDmc, miInfo);
272
		}
273
	}
274
275
	private AbstractMIControl fConnection;
262
	private CommandCache fMICommandCache;
276
	private CommandCache fMICommandCache;
263
    
277
    
264
    // state flags
278
    // State flags
265
	private boolean fSuspended = true;
279
	private boolean fSuspended = true;
266
    private boolean fResumePending = false;
280
    private boolean fResumePending = false;
267
	private boolean fStepping = false;
281
	private boolean fStepping = false;
Lines 291-299 Link Here
291
        fMICommandCache = new CommandCache(getSession(), fConnection);
305
        fMICommandCache = new CommandCache(getSession(), fConnection);
292
        fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
306
        fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
293
        getSession().addServiceEventListener(this, null);
307
        getSession().addServiceEventListener(this, null);
294
        
295
        //register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>());
296
        
297
        rm.done();
308
        rm.done();
298
    }
309
    }
299
310
(-)src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java (-26 / +9 lines)
Lines 57-63 Link Here
57
    // Last Thread ID created 
57
    // Last Thread ID created 
58
	private static int fLastThreadId;
58
	private static int fLastThreadId;
59
    
59
    
60
	
61
    public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) {
60
    public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) {
62
        fCommandControl = connection;
61
        fCommandControl = connection;
63
        fInferior = inferior;
62
        fInferior = inferior;
Lines 109-140 Link Here
109
            fEventList.add(oobr);
108
            fEventList.add(oobr);
110
            
109
            
111
            if (oobr instanceof MIConsoleStreamOutput) {
110
            if (oobr instanceof MIConsoleStreamOutput) {
112
                // Process Events of type DsfMIConsoleStreamOutput here
111
            	// Process Events of type DsfMIConsoleStreamOutput here
113
                MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr;
112
            	MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr;
114
113
115
                // Look for events with Pattern ^[New Thread 1077300144 (LWP 7973)
114
            	// Look for events with Pattern ^[New Thread 1077300144 (LWP 7973)
116
                Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)",  Pattern.MULTILINE); //$NON-NLS-1$
115
            	Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$
117
                Matcher matcher = pattern.matcher(exec.getCString());
116
            	Matcher matcher = pattern.matcher(exec.getCString());
118
                if (matcher.find()) {
117
            	if (matcher.find()) {
119
                	//fMapThreadIds.put(matcher.group(2), Integer.valueOf(++fLastThreadId));
118
            		MIEvent<?> e =  new MIThreadCreatedEvent(fContainerDmc, ++fLastThreadId);
120
                    //DsfMIEvent e =  new DsfMIThreadCreatedEvent(Integer.valueOf(matcher.group(2)));
119
            		fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties());
121
                    MIEvent<?> e =  new MIThreadCreatedEvent(fContainerDmc, ++fLastThreadId);
120
            	}
122
                    // Dispatch DsfMIThreadCreatedEvent
123
                    fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties());
124
                }
125
                // HACK -  For GDB thread exit events, we won't use the events generated by GDB. This event is 
126
                // raised in GDBRunControl class by polling and comparing the ExecutionContexts returned by
127
                // -thread-list-ids command. This is done as threads reported by exit event are still reported till 
128
                // they completely exit the system.
129
                // Look for Thread Exited Event with Pattern [Thread 1077300144 (LWP 23832) exited]\n
130
                // See bug 200615 for details.
131
//                pattern = Pattern.compile("(^\\[Thread.*LWP\\s)(\\d*)(.*exited.*$)",  Pattern.MULTILINE); //$NON-NLS-1$
132
//                matcher = pattern.matcher(exec.getCString());
133
//                if (matcher.find()) {
134
//                    DsfMIEvent e =  new DsfMIThreadExitEvent(fMapThreadIds.get(matcher.group(2)).intValue());
135
//                    // Dispatch DsfMIThreadExitEvent
136
//                    fConnection.getSession().dispatchEvent(e, fConnection.getProperties());
137
//                }
138
            }
121
            }
139
        }
122
        }
140
        
123
        
(-)src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java (-51 / +91 lines)
Lines 22-28 Link Here
22
import org.eclipse.dd.dsf.debug.service.command.IEventListener;
22
import org.eclipse.dd.dsf.debug.service.command.IEventListener;
23
import org.eclipse.dd.dsf.service.DsfServicesTracker;
23
import org.eclipse.dd.dsf.service.DsfServicesTracker;
24
import org.eclipse.dd.mi.internal.MIPlugin;
24
import org.eclipse.dd.mi.internal.MIPlugin;
25
import org.eclipse.dd.mi.service.MIRunControl;
25
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
26
import org.eclipse.dd.mi.service.IMIRunControl;
26
import org.eclipse.dd.mi.service.command.commands.MIExecContinue;
27
import org.eclipse.dd.mi.service.command.commands.MIExecContinue;
27
import org.eclipse.dd.mi.service.command.commands.MIExecFinish;
28
import org.eclipse.dd.mi.service.command.commands.MIExecFinish;
28
import org.eclipse.dd.mi.service.command.commands.MIExecNext;
29
import org.eclipse.dd.mi.service.command.commands.MIExecNext;
Lines 41-46 Link Here
41
import org.eclipse.dd.mi.service.command.events.MISignalEvent;
42
import org.eclipse.dd.mi.service.command.events.MISignalEvent;
42
import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
43
import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
43
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
44
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
45
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
46
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
44
import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent;
47
import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent;
45
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
48
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
46
import org.eclipse.dd.mi.service.command.output.MIConst;
49
import org.eclipse.dd.mi.service.command.output.MIConst;
Lines 51-57 Link Here
51
import org.eclipse.dd.mi.service.command.output.MIOutput;
54
import org.eclipse.dd.mi.service.command.output.MIOutput;
52
import org.eclipse.dd.mi.service.command.output.MIResult;
55
import org.eclipse.dd.mi.service.command.output.MIResult;
53
import org.eclipse.dd.mi.service.command.output.MIResultRecord;
56
import org.eclipse.dd.mi.service.command.output.MIResultRecord;
54
import org.eclipse.dd.mi.service.command.output.MIStatusAsyncOutput;
55
import org.eclipse.dd.mi.service.command.output.MIValue;
57
import org.eclipse.dd.mi.service.command.output.MIValue;
56
58
57
/**
59
/**
Lines 102-158 Link Here
102
    }
104
    }
103
    
105
    
104
    public void eventReceived(Object output) {
106
    public void eventReceived(Object output) {
105
        for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) {
107
    	for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) {
106
            if (oobr instanceof MIExecAsyncOutput) {
108
			List<MIEvent<?>> events = new LinkedList<MIEvent<?>>();
107
            	MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr;
109
    		if (oobr instanceof MIExecAsyncOutput) {
108
                // Change of state.
110
    			MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr;
109
                String state = exec.getAsyncClass();
111
    			// Change of state.
110
                if ("stopped".equals(state)) { //$NON-NLS-1$
112
    			String state = exec.getAsyncClass();
111
                	// Re-set the thread and stack level to -1 when stopped event is recvd. 
113
    			if ("stopped".equals(state)) { //$NON-NLS-1$
112
                	// This is to synchronize the state between GDB back-end and AbstractMIControl. 
114
    				// Re-set the thread and stack level to -1 when stopped event is recvd. 
113
                	fCommandControl.resetCurrentThreadLevel();
115
    				// This is to synchronize the state between GDB back-end and AbstractMIControl. 
114
                	fCommandControl.resetCurrentStackLevel();
116
    				fCommandControl.resetCurrentThreadLevel();
115
                	
117
    				fCommandControl.resetCurrentStackLevel();
116
                    List<MIEvent<?>> events = new LinkedList<MIEvent<?>>();
118
117
                    MIResult[] results = exec.getMIResults();
119
    				MIResult[] results = exec.getMIResults();
118
                    for (int i = 0; i < results.length; i++) {
120
    				for (int i = 0; i < results.length; i++) {
119
                        String var = results[i].getVariable();
121
    					String var = results[i].getVariable();
120
                        MIValue val = results[i].getMIValue();
122
    					MIValue val = results[i].getMIValue();
121
                        if (var.equals("reason")) { //$NON-NLS-1$
123
    					if (var.equals("reason")) { //$NON-NLS-1$
122
                            if (val instanceof MIConst) {
124
    						if (val instanceof MIConst) {
123
                                String reason = ((MIConst) val).getString();
125
    							String reason = ((MIConst) val).getString();
124
                                MIEvent<?> e = createEvent(reason, exec);
126
    							MIEvent<?> e = createEvent(reason, exec);
125
                                if (e != null) {
127
    							if (e != null) {
126
                                    events.add(e);
128
    								events.add(e);
127
                                    continue;
129
    								continue;
128
                                }
130
    							}
129
                            }
131
    						}
130
                        }
132
    					}
131
                    }
133
    				}
132
    
134
        			// We were stopped for some unknown reason, for example
133
                    // We were stopped for some unknown reason, for example
135
        			// GDB for temporary breakpoints will not send the
134
                    // GDB for temporary breakpoints will not send the
136
        			// "reason" ??? still fire a stopped event.
135
                    // "reason" ??? still fire a stopped event.
137
        			if (events.isEmpty()) {
136
                    if (events.isEmpty()) {
138
        				MIEvent<?> e = MIStoppedEvent.parse(
137
                    	MIEvent<?> e = MIStoppedEvent.parse(
139
        						fServicesTracker.getService(IMIRunControl.class), fContainerDmc, exec.getToken(), exec.getMIResults());
138
                    	    fServicesTracker.getService(MIRunControl.class), fContainerDmc, exec.getToken(), exec.getMIResults());
140
        				events.add(e);
139
                        events.add(e);
141
        			}
140
                    }
142
141
                    for (MIEvent<?> event : events) {
143
        			for (MIEvent<?> event : events) {
142
                        fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
144
        				fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
143
                    }
145
        			}
144
                }
146
    			}
145
            } 
147
    			else if ("running".equals(state)) { //$NON-NLS-1$
146
            else if (oobr instanceof MIStatusAsyncOutput) {
148
    				int token = exec.getToken();
147
                // Nothing done .. but what about +download??
149
    				MIResult[] results = exec.getMIResults();
148
            } else if (oobr instanceof MINotifyAsyncOutput) {
150
    				for (int i = 0; i < results.length; i++) {
149
                // Nothing
151
    					String var = results[i].getVariable();
150
            }        
152
    					MIValue val = results[i].getMIValue();
151
        }
153
    					if (var.equals("thread-id")) { //$NON-NLS-1$
154
    						if (val instanceof MIConst) {
155
    							String thread = ((MIConst) val).getString();
156
    							MIEvent<?> evt = null;
157
    							int threadId = 0;
158
    							try {
159
    								threadId = Integer.parseInt(thread);
160
        							IMIExecutionDMContext context = fServicesTracker.getService(IMIRunControl.class).createMIExecutionContext(fContainerDmc, threadId);
161
        							evt = new MIRunningEvent(context, token, MIRunningEvent.CONTINUE);
162
    							}
163
    							catch (NumberFormatException e) {
164
        							evt = new MIRunningEvent(fContainerDmc, token, MIRunningEvent.CONTINUE);
165
    								
166
    							}
167
    	        				fCommandControl.getSession().dispatchEvent(evt, fCommandControl.getProperties());
168
    						}
169
    					}
170
    				}
171
    			}
172
173
    		} 
174
    		else if (oobr instanceof MINotifyAsyncOutput) {
175
    			// Parse the string and dispatch the corresponding event
176
    			MINotifyAsyncOutput exec = (MINotifyAsyncOutput) oobr;
177
    			String miEvent = exec.getAsyncClass();
178
    			if ("thread-created".equals(miEvent)) { //$NON-NLS-1$
179
    				MIEvent<?> event = MIThreadCreatedEvent.parse(fContainerDmc, exec.getToken(), exec.getMIResults());
180
    				if (event != null) {
181
    					fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
182
    				}
183
    			}
184
    			else if ("thread-exited".equals(miEvent)) { //$NON-NLS-1$
185
    				MIEvent<?> event = MIThreadExitEvent.parse(fContainerDmc, exec.getToken(), exec.getMIResults());
186
    				if (event != null) {
187
    					fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
188
    				}
189
    			}
190
    		}
191
    	}
152
    }
192
    }
153
    
193
    
154
    protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) {
194
    protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) {
155
        MIRunControl runControl = fServicesTracker.getService(MIRunControl.class);
195
        IMIRunControl runControl = fServicesTracker.getService(IMIRunControl.class);
156
        MIEvent<?> event = null;
196
        MIEvent<?> event = null;
157
        if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$
197
        if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$
158
                event = MIBreakpointHitEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults());
198
                event = MIBreakpointHitEvent.parse(runControl, fContainerDmc, exec.getToken(), exec.getMIResults());
Lines 213-219 Link Here
213
                else if (cmd instanceof MIExecFinish)          { type = MIRunningEvent.FINISH; }
253
                else if (cmd instanceof MIExecFinish)          { type = MIRunningEvent.FINISH; }
214
                else if (cmd instanceof MIExecReturn)          { type = MIRunningEvent.RETURN; }
254
                else if (cmd instanceof MIExecReturn)          { type = MIRunningEvent.RETURN; }
215
                else if (cmd instanceof MIExecContinue)        { type = MIRunningEvent.CONTINUE; }
255
                else if (cmd instanceof MIExecContinue)        { type = MIRunningEvent.CONTINUE; }
216
                else                                              { type = MIRunningEvent.CONTINUE; }
256
                else                                           { type = MIRunningEvent.CONTINUE; }
217
                
257
                
218
                fCommandControl.getSession().dispatchEvent(
258
                fCommandControl.getSession().dispatchEvent(
219
                    new MIRunningEvent(fContainerDmc, id, type), fCommandControl.getProperties());
259
                    new MIRunningEvent(fContainerDmc, id, type), fCommandControl.getProperties());
(-)src/org/eclipse/dd/mi/service/command/AbstractMIControl.java (-32 / +38 lines)
Lines 31-36 Link Here
31
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
31
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
32
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
32
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
33
import org.eclipse.dd.dsf.datamodel.DMContexts;
33
import org.eclipse.dd.dsf.datamodel.DMContexts;
34
import org.eclipse.dd.dsf.datamodel.IDMContext;
35
import org.eclipse.dd.dsf.debug.service.IRunControl;
34
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
36
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
35
import org.eclipse.dd.dsf.debug.service.command.ICommand;
37
import org.eclipse.dd.dsf.debug.service.command.ICommand;
36
import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
38
import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
Lines 74-80 Link Here
74
    private RxThread fRxThread;
76
    private RxThread fRxThread;
75
    
77
    
76
    private int fCurrentStackLevel = -1;
78
    private int fCurrentStackLevel = -1;
77
    private int fCurrentThreadId = -1;
79
    private int fCurrentThreadId   = -1;
78
    
80
    
79
    
81
    
80
    private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
82
    private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
Lines 85-91 Link Here
85
     * that the TX thread should shut down.
87
     * that the TX thread should shut down.
86
     */
88
     */
87
    private final CommandHandle fTerminatorHandle = new CommandHandle(null, null);
89
    private final CommandHandle fTerminatorHandle = new CommandHandle(null, null);
88
    
89
90
90
    /*
91
    /*
91
     *   Various listener control variables used to keep track of listeners who want to monitor
92
     *   Various listener control variables used to keep track of listeners who want to monitor
Lines 207-213 Link Here
207
        // Cast the return token to match the result type of MI Command.  This is checking
208
        // Cast the return token to match the result type of MI Command.  This is checking
208
        // against an erased type so it should never throw any exceptions.
209
        // against an erased type so it should never throw any exceptions.
209
        @SuppressWarnings("unchecked")
210
        @SuppressWarnings("unchecked")
210
        DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>)rm;
211
        DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>) rm;
211
212
212
        final CommandHandle handle = new CommandHandle(miCommand, miDone);
213
        final CommandHandle handle = new CommandHandle(miCommand, miDone);
213
214
Lines 240-277 Link Here
240
    }
241
    }
241
242
242
    private void processNextQueuedCommand() {
243
    private void processNextQueuedCommand() {
243
		if ( fCommandQueue.size() > 0 ) {
244
		if (fCommandQueue.size() > 0) {
244
			CommandHandle handle = fCommandQueue.remove(0);
245
			final CommandHandle handle = fCommandQueue.remove(0);
245
			if ( handle != null ) {
246
			if (handle != null) {
246
				processCommandSent(handle);
247
				processCommandSent(handle);
247
248
248
				// Before the command is sent, Check the Thread Id and send it to 
249
				// Identify target thread/frame (we might have to update them at the target)
249
				// the queue only if the id has been changed.
250
				final IDMContext targetContext = handle.fCommand.getContext();
250
				if( handle.getThreadId()!= null && 
251
				final int targetThread = (handle.getThreadId()     != null) ? handle.getThreadId().intValue()     : -1;
251
						handle.getThreadId().intValue() != fCurrentThreadId && handle.getThreadId().intValue() != 0)
252
				final int targetFrame  = (handle.getStackFrameId() != null) ? handle.getStackFrameId().intValue() : -1;
252
				{
253
253
					// Re-set the level
254
			    // The thread-select and frame-select make sense only if the thread is stopped.
254
					fCurrentThreadId = handle.getThreadId().intValue();
255
				// Some non-stop commands don't require the thread to be stopped so we send the
255
					CommandHandle cmdHandle = new CommandHandle(
256
				// command anyway.
256
							new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null);
257
			    IRunControl runControl = getServicesTracker().getService(IRunControl.class);
257
					cmdHandle.generateTokenId();
258
				IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(targetContext, IMIExecutionDMContext.class);
258
					fTxCommands.add(cmdHandle);
259
				if (runControl != null && execDmc != null && runControl.isSuspended(execDmc)) {
259
				}
260
			    	// Before the command is sent, Check the Thread Id and send it to 
260
261
			    	// the queue only if the id has been changed.
261
				// Before the command is sent, Check the Stack level and send it to 
262
			    	if (targetThread != -1 && targetThread != fCurrentThreadId) {
262
				// the queue only if the level has been changed. 
263
			    		fCurrentThreadId = targetThread;
263
				if( handle.getStackFrameId()!= null && 
264
			    		resetCurrentStackLevel();
264
						handle.getStackFrameId().intValue() != fCurrentStackLevel)
265
			    		CommandHandle cmdHandle = new CommandHandle(new MIThreadSelect(execDmc), null);
265
				{
266
			    		cmdHandle.generateTokenId();
266
					// Re-set the level
267
			    		fTxCommands.add(cmdHandle);
267
					fCurrentStackLevel = handle.getStackFrameId().intValue();
268
			    	}
268
					CommandHandle cmdHandle = new CommandHandle(
269
269
							new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null);
270
			    	// Before the command is sent, Check the Stack level and send it to 
270
					cmdHandle.generateTokenId();
271
			    	// the queue only if the level has been changed. 
271
					fTxCommands.add(cmdHandle);
272
			    	if (targetFrame != -1 && targetFrame != fCurrentStackLevel) {
273
			    		fCurrentStackLevel = targetFrame;
274
			    		CommandHandle cmdHandle = new CommandHandle(new MIStackSelectFrame(execDmc, targetFrame), null);
275
			    		cmdHandle.generateTokenId();
276
			    		fTxCommands.add(cmdHandle);
277
			    	}
272
				}
278
				}
273
				handle.generateTokenId();
279
		    	handle.generateTokenId();
274
				fTxCommands.add(handle);
280
		    	fTxCommands.add(handle);
275
			}
281
			}
276
		}
282
		}
277
    }
283
    }
(-)src/org/eclipse/dd/mi/service/command/output/CLIInfoThreadsInfo.java (-1 / +1 lines)
Lines 35-41 Link Here
35
		parse();
35
		parse();
36
	}
36
	}
37
37
38
	public class ThreadInfo{
38
	public class ThreadInfo {
39
		String fName;
39
		String fName;
40
		String fGdbId;
40
		String fGdbId;
41
		String fPid;
41
		String fPid;
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 13-18 Link Here
13
 org.eclipse.cdt.debug.core,
13
 org.eclipse.cdt.debug.core,
14
 org.eclipse.cdt.core
14
 org.eclipse.cdt.core
15
Export-Package: 
15
Export-Package: 
16
 org.eclipse.dd.mi.internal,
16
 org.eclipse.dd.mi.service,
17
 org.eclipse.dd.mi.service,
17
 org.eclipse.dd.mi.service.command,
18
 org.eclipse.dd.mi.service.command,
18
 org.eclipse.dd.mi.service.command.commands,
19
 org.eclipse.dd.mi.service.command.commands,
(-)src/org/eclipse/dd/mi/service/IMIRunControl.java (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *     Ericsson			  - Modified for additional functionality
11
 *******************************************************************************/
12
package org.eclipse.dd.mi.service;
13
14
import org.eclipse.dd.dsf.debug.service.IRunControl;
15
16
/**
17
 * This interface provides access to controlling and monitoring the execution 
18
 * state of a process being debugged.  This interface does not actually 
19
 * provide methods for creating or destroying execution contexts, it doesn't
20
 * even have methods for getting labels.  That's because it is expected that
21
 * higher level services, ones that deal with processes, kernels, or target 
22
 * features will provide that functionality. 
23
 */
24
public interface IMIRunControl extends IRunControl
25
{
26
	public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId);
27
}
(-)src/org/eclipse/dd/mi/service/MIStackNS.java (+677 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *     Ericsson			  - Modified for handling of multiple execution contexts	
11
 *******************************************************************************/
12
package org.eclipse.dd.mi.service;
13
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.Hashtable;
17
import java.util.List;
18
19
import org.eclipse.cdt.core.IAddress;
20
import org.eclipse.cdt.utils.Addr32;
21
import org.eclipse.cdt.utils.Addr64;
22
import org.eclipse.core.runtime.IStatus;
23
import org.eclipse.core.runtime.Status;
24
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
25
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
26
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
27
import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
28
import org.eclipse.dd.dsf.datamodel.DMContexts;
29
import org.eclipse.dd.dsf.datamodel.IDMContext;
30
import org.eclipse.dd.dsf.debug.service.IStack;
31
import org.eclipse.dd.dsf.debug.service.IStack2;
32
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
33
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
34
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
35
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
36
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
37
import org.eclipse.dd.dsf.service.AbstractDsfService;
38
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
39
import org.eclipse.dd.dsf.service.DsfSession;
40
import org.eclipse.dd.mi.internal.MIPlugin;
41
import org.eclipse.dd.mi.service.command.AbstractMIControl;
42
import org.eclipse.dd.mi.service.command.commands.MIStackInfoDepth;
43
import org.eclipse.dd.mi.service.command.commands.MIStackListArguments;
44
import org.eclipse.dd.mi.service.command.commands.MIStackListFrames;
45
import org.eclipse.dd.mi.service.command.commands.MIStackListLocals;
46
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
47
import org.eclipse.dd.mi.service.command.events.MIEvent;
48
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
49
import org.eclipse.dd.mi.service.command.output.MIArg;
50
import org.eclipse.dd.mi.service.command.output.MIFrame;
51
import org.eclipse.dd.mi.service.command.output.MIStackInfoDepthInfo;
52
import org.eclipse.dd.mi.service.command.output.MIStackListArgumentsInfo;
53
import org.eclipse.dd.mi.service.command.output.MIStackListFramesInfo;
54
import org.eclipse.dd.mi.service.command.output.MIStackListLocalsInfo;
55
import org.osgi.framework.BundleContext;
56
57
public class MIStackNS extends AbstractDsfService
58
	implements IStack2
59
{
60
    protected static class MIFrameDMC extends AbstractDMContext 
61
        implements IFrameDMContext
62
    {
63
        private final int fLevel;
64
        // public MIFrameDMC(MIStack service, int level) {
65
        public MIFrameDMC(String sessionId, IExecutionDMContext execDmc, int level) {
66
            super(sessionId, new IDMContext[] { execDmc });
67
            fLevel = level;
68
        }
69
        
70
        public int getLevel() { return fLevel; }
71
        
72
        @Override
73
        public boolean equals(Object other) {
74
            return super.baseEquals(other) && ((MIFrameDMC)other).fLevel == fLevel;
75
        }
76
        
77
        @Override
78
        public int hashCode() {
79
            return super.baseHashCode() ^ fLevel;
80
        }
81
        
82
        @Override
83
        public String toString() { 
84
            return baseToString() + ".frame[" + fLevel + "]";  //$NON-NLS-1$ //$NON-NLS-2$
85
        }            
86
    }
87
       
88
    protected static class MIVariableDMC extends AbstractDMContext
89
        implements IVariableDMContext
90
    {
91
        public enum Type { ARGUMENT, LOCAL }
92
        final private Type fType;
93
        final private int fIndex;
94
95
        public MIVariableDMC(MIStackNS service, IFrameDMContext frame, Type type, int index) {
96
            super(service, new IDMContext[] { frame });
97
            fIndex = index;
98
            fType = type;
99
        }
100
        
101
        public int getIndex() { return fIndex; }
102
        public Type getType() { return fType; }
103
        
104
        @Override
105
        public boolean equals(Object other) {
106
            return super.baseEquals(other) && 
107
                   ((MIVariableDMC)other).fType == fType && 
108
                   ((MIVariableDMC)other).fIndex == fIndex;
109
        }
110
        
111
        @Override
112
        public int hashCode() {
113
            int typeFactor = 0;
114
            if (fType == Type.LOCAL) typeFactor = 2;
115
            else if (fType == Type.ARGUMENT) typeFactor = 3;
116
            return super.baseHashCode() ^ typeFactor ^ fIndex;
117
        }
118
        
119
        @Override
120
        public String toString() { 
121
            return baseToString() + ".variable(" + fType + ")[" + fIndex + "]";  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
122
        }            
123
    }
124
    
125
	private CommandCache   fMICommandCache;
126
    private MIStoppedEvent fCachedStoppedEvent;
127
    private IMIRunControl  fMIRunControl;
128
129
	public MIStackNS(DsfSession session) 
130
	{
131
		super(session);
132
	}
133
134
    @Override
135
    protected BundleContext getBundleContext() 
136
    {
137
        return MIPlugin.getBundleContext();
138
    }
139
    
140
    @Override
141
    public void initialize(final RequestMonitor rm) {
142
        super.initialize(
143
            new RequestMonitor(getExecutor(), rm) { 
144
                @Override
145
                protected void handleSuccess() {
146
                    doInitialize(rm);
147
                }
148
            });
149
    }
150
151
    private void doInitialize(RequestMonitor rm) {
152
        AbstractMIControl miControl = getServicesTracker().getService(AbstractMIControl.class);
153
        fMICommandCache = new CommandCache(getSession(), miControl);
154
        fMICommandCache.setContextAvailable(miControl.getControlDMContext(), true);
155
	    fMIRunControl = getServicesTracker().getService(IMIRunControl.class);
156
        
157
        getSession().addServiceEventListener(this, null);
158
        register(new String[]{IStack.class.getName(), MIStackNS.class.getName()}, new Hashtable<String,String>());
159
        rm.done();
160
    }
161
162
    @Override
163
    public void shutdown(RequestMonitor rm) 
164
    {
165
        unregister();
166
        getSession().removeServiceEventListener(this);
167
        fMICommandCache.reset();
168
        super.shutdown(rm);
169
    }
170
171
    @SuppressWarnings("unchecked")
172
    public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
173
        if (dmc instanceof MIFrameDMC) {
174
            getFrameData((MIFrameDMC)dmc, (DataRequestMonitor<IFrameDMData>)rm);
175
            // getFrameData invokes rm 
176
        } else if (dmc instanceof MIVariableDMC) {
177
            getVariableData((MIVariableDMC)dmc, (DataRequestMonitor<IVariableDMData>)rm);
178
            // getVariablesData invokes rm 
179
        } else {
180
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
181
            rm.done();
182
        }
183
    }
184
185
    /**
186
     * Creates a frame context.  This method is intended to be used by other MI 
187
     * services and sub-classes which need to create a frame context directly.
188
     * <p>
189
     * Sub-classes can override this method to provide custom stack frame 
190
     * context implementation. 
191
     * </p>
192
     * @param execDmc Execution context that this frame is to be a child of.
193
     * @param level Level of the new context.
194
     * @return A new frame context.
195
     */
196
    public IFrameDMContext createFrameDMContext(IExecutionDMContext execDmc, int level) {
197
        return new MIFrameDMC(getSession().getId(), execDmc, level);
198
    }
199
    
200
    public void getFrames(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext[]> rm) {
201
    	getFrames(ctx, 0, ALL_FRAMES, rm);
202
    }
203
204
	public void getFrames(final IDMContext ctx, final int startIndex, final int endIndex, final DataRequestMonitor<IFrameDMContext[]> rm) {
205
206
		// Make sure we have an execution context (ideally a thread)
207
		final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class);
208
	    if (execDmc == null) {
209
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context " + ctx, null)); //$NON-NLS-1$
210
            rm.done();
211
            return;
212
        }
213
214
	    // Make sure the indices are OK
215
	    if (startIndex < 0 || endIndex > 0 && endIndex < startIndex) {
216
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid stack frame range [" + startIndex + ',' + endIndex + ']', null)); //$NON-NLS-1$
217
            rm.done();
218
            return;
219
	    }
220
221
	    // Make sure the thread is stopped
222
	    if (!fMIRunControl.isSuspended(execDmc)) {
223
	    	rm.setData(new IFrameDMContext[0]);
224
	    	rm.done();
225
	    	return;
226
	    }
227
228
        // Case of retrieving the top stack frame from the cached stopped event.
229
	    if (startIndex == 0 && endIndex == 0) {
230
	        if (fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null && 
231
	            execDmc.equals(fCachedStoppedEvent.getDMContext())) 
232
	        {
233
	            rm.setData(new IFrameDMContext[] { createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel()) });
234
	            rm.done();
235
	            return;
236
	        }
237
	    }
238
239
	    // Select the proper MI command variant
240
	    final MIStackListFrames miStackListCmd;
241
	    final int firstIndex;
242
	    if (endIndex >= 0) {
243
	    	miStackListCmd = new MIStackListFrames(execDmc, true, startIndex, endIndex);
244
	    	firstIndex = startIndex;
245
	    } else {
246
	    	miStackListCmd = new MIStackListFrames(execDmc, true);
247
	    	firstIndex = 0;
248
	    }
249
250
	    // And go...
251
	    fMICommandCache.execute(
252
            miStackListCmd,
253
            new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) { 
254
                @Override
255
                protected void handleSuccess() {
256
                    rm.setData(getFrames(execDmc, getData(), firstIndex, endIndex, startIndex));
257
                    rm.done();
258
                }
259
            });
260
	}
261
    
262
    public void getTopFrame(final IDMContext ctx, final DataRequestMonitor<IFrameDMContext> rm) {     
263
        final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class);
264
        if (execDmc == null) {
265
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context" + ctx, null)); //$NON-NLS-1$
266
            rm.done();
267
            return;
268
        }
269
        
270
        // Try to retrieve the top stack frame from the cached stopped event.
271
        if (fCachedStoppedEvent != null && 
272
            fCachedStoppedEvent.getFrame() != null && 
273
            execDmc.equals(fCachedStoppedEvent.getDMContext())) 
274
        {
275
            rm.setData(createFrameDMContext(execDmc, fCachedStoppedEvent.getFrame().getLevel()));
276
            rm.done();
277
            return;
278
        }
279
        
280
        // If stopped event is not available or doesn't contain frame info, 
281
        // query top stack frame
282
        getFrames(
283
            ctx, 
284
            0,
285
            0,
286
            new DataRequestMonitor<IFrameDMContext[]>(getExecutor(), rm) { 
287
                @Override
288
                protected void handleSuccess() {
289
                    rm.setData(getData()[0]);
290
                    rm.done();
291
                }
292
            });
293
    }
294
    
295
    //private MIFrameDMC[] getFrames(DsfMIStackListFramesInfo info) {
296
    private IFrameDMContext[] getFrames(IMIExecutionDMContext execDmc, MIStackListFramesInfo info, int firstIndex, int lastIndex, int startIndex) {
297
        int length = info.getMIFrames().length;
298
        if (lastIndex > 0) {
299
        	int limit= lastIndex - startIndex + 1;
300
        	if (limit < length) {
301
        		length = limit;
302
        	}
303
        }
304
		IFrameDMContext[] frameDMCs = new MIFrameDMC[length];
305
        for (int i = 0; i < length; i++) {
306
	        //frameDMCs[i] = new MIFrameDMC(this, info.getMIFrames()[i].getLevel()); 
307
        	final MIFrame frame= info.getMIFrames()[i + startIndex - firstIndex];
308
			assert startIndex + i == frame.getLevel();
309
            frameDMCs[i] = createFrameDMContext(execDmc, frame.getLevel()); 
310
        }
311
        return frameDMCs;
312
    }
313
    
314
315
    
316
    public void getFrameData(final IFrameDMContext frameDmc, final DataRequestMonitor<IFrameDMData> rm) {
317
        if (!(frameDmc instanceof MIFrameDMC)) {
318
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + frameDmc, null)); //$NON-NLS-1$
319
            rm.done();
320
            return;
321
        }
322
323
        final MIFrameDMC miFrameDmc = (MIFrameDMC)frameDmc;
324
        
325
        IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class);
326
        if (execDmc == null) { 
327
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$
328
            rm.done();
329
            return;
330
        }
331
332
        /**
333
         * Base class for the IFrameDMData object that uses an MIFrame object to 
334
         * provide the data.  Sub-classes must provide the MIFrame object
335
         */
336
        abstract class FrameData implements IFrameDMData
337
        {
338
            abstract protected MIFrame getMIFrame();
339
340
            public IAddress getAddress() {
341
                String addr = getMIFrame().getAddress();
342
                if (addr.startsWith("0x")) { //$NON-NLS-1$
343
                    addr = addr.substring(2);
344
                }
345
                if (addr.length() <= 8) {
346
                    return new Addr32(getMIFrame().getAddress());
347
                } else {
348
                    return new Addr64(getMIFrame().getAddress());
349
                }                    
350
            }
351
352
            public int getColumn() { return 0; }
353
354
            public String getFile() { return getMIFrame().getFile(); }
355
            public int getLine() { return getMIFrame().getLine(); }
356
            public String getFunction() { return getMIFrame().getFunction(); }
357
            
358
            @Override
359
            public String toString() { return getMIFrame().toString(); }
360
        }
361
362
        // If requested frame is the top stack frame, try to retrieve it from 
363
        // the stopped event data.
364
        class FrameDataFromStoppedEvent extends FrameData {
365
            private final MIStoppedEvent fEvent;
366
            FrameDataFromStoppedEvent(MIStoppedEvent event) { fEvent = event; }
367
            @Override
368
            protected MIFrame getMIFrame() { return fEvent.getFrame(); }
369
        }
370
        
371
        // Retrieve the top stack frame from the stopped event only if the selected thread is the one on which stopped event 
372
        // is raised
373
        if (fCachedStoppedEvent != null && 
374
            execDmc.equals(fCachedStoppedEvent.getDMContext()) && 
375
            miFrameDmc.fLevel == 0 && 
376
            fCachedStoppedEvent.getFrame() != null) 
377
        {
378
            rm.setData(new FrameDataFromStoppedEvent(fCachedStoppedEvent));
379
            rm.done();
380
            return;
381
        } 
382
383
        // If not, retrieve the full list of frame data.
384
        class FrameDataFromMIStackFrameListInfo extends FrameData {
385
            private MIStackListFramesInfo fFrameDataCacheInfo;
386
            private int fFrameIndex;
387
388
            FrameDataFromMIStackFrameListInfo(MIStackListFramesInfo info, int index) {
389
                fFrameDataCacheInfo = info;
390
                fFrameIndex = index;
391
            }
392
393
            @Override
394
            protected MIFrame getMIFrame() { return fFrameDataCacheInfo.getMIFrames()[fFrameIndex]; }
395
        }
396
397
        fMICommandCache.execute(
398
            new MIStackListFrames(execDmc, true),
399
            new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) { 
400
                @Override
401
                protected void handleSuccess() {
402
                    // Find the index to the correct MI frame object.
403
                    int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel);
404
                    if (idx == -1) {
405
                        rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid frame " + frameDmc, null));  //$NON-NLS-1$
406
                        rm.done();
407
                        return;
408
                    }
409
                    
410
                    // Create the data object.
411
                    rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx));
412
                    rm.done();
413
                }
414
            }); 
415
    }
416
417
	public void getArguments(final IFrameDMContext frameDmc, final DataRequestMonitor<IVariableDMContext[]> rm) {
418
        final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class);
419
	    if (execDmc == null) { 
420
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$
421
            rm.done();
422
            return;
423
        }
424
425
        
426
        // If requested frame is the top stack frame, try to retrieve it from 
427
        // the stopped event data.
428
        if (frameDmc.getLevel() == 0 && 
429
            fCachedStoppedEvent != null && 
430
            fCachedStoppedEvent.getFrame() != null &&
431
            execDmc.equals(fCachedStoppedEvent.getDMContext()) && 
432
            fCachedStoppedEvent.getFrame().getArgs() != null) 
433
        {
434
            rm.setData(makeVariableDMCs(
435
                frameDmc, MIVariableDMC.Type.ARGUMENT, fCachedStoppedEvent.getFrame().getArgs().length)); 
436
            rm.done();
437
            return;
438
        }
439
440
        // If not, retrieve the full list of frame data.
441
        fMICommandCache.execute(
442
            new MIStackListArguments(execDmc, true, true),
443
            new DataRequestMonitor<MIStackListArgumentsInfo>(getExecutor(), rm) { 
444
                @Override
445
                protected void handleSuccess() {
446
                    // Find the index to the correct MI frame object.
447
                    // Note: this is a short-cut, but it won't work once we implement retrieving
448
                    // partial lists of stack frames.
449
                    int idx = frameDmc.getLevel();
450
                    if (idx == -1 || idx >= getData().getMIFrames().length) {
451
                        rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE, "Invalid frame " + frameDmc, null));  //$NON-NLS-1$
452
                        rm.done();
453
                        return;
454
                    }
455
                    
456
                    // Create the variable array out of MIArg array.
457
                    MIArg[] args = getData().getMIFrames()[idx].getArgs();
458
                    if (args == null) args = new MIArg[0]; 
459
                    rm.setData(makeVariableDMCs(frameDmc, MIVariableDMC.Type.ARGUMENT, args.length));
460
                    rm.done();
461
                }
462
            }); 
463
    }    
464
    
465
    public void getVariableData(IVariableDMContext variableDmc, final DataRequestMonitor<IVariableDMData> rm) {
466
        if (!(variableDmc instanceof MIVariableDMC)) {
467
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context type " + variableDmc, null)); //$NON-NLS-1$
468
            rm.done();
469
            return;            
470
        }
471
        final MIVariableDMC miVariableDmc = (MIVariableDMC)variableDmc;
472
        
473
        // Extract the frame DMC from the variable DMC.
474
        final MIFrameDMC frameDmc = DMContexts.getAncestorOfType(variableDmc, MIFrameDMC.class);
475
        if (frameDmc == null) { 
476
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No frame context found in " + variableDmc, null)); //$NON-NLS-1$
477
            rm.done();
478
            return;
479
        }
480
481
        final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class);
482
        if (execDmc == null) { 
483
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "No execution context found in " + frameDmc, null)); //$NON-NLS-1$
484
            rm.done();
485
            return;
486
        }
487
488
        /**
489
         * Same as with frame objects, this is a base class for the IVariableDMData object that uses an MIArg object to 
490
         * provide the data.  Sub-classes must supply the MIArg object.
491
         */
492
    	class VariableData implements IVariableDMData {
493
    		private MIArg dsfMIArg;
494
    		VariableData(MIArg arg){
495
    			dsfMIArg = arg;
496
    		}
497
    		public String getName() { return dsfMIArg.getName(); }
498
    		public String getValue() { return dsfMIArg.getValue(); }
499
    		@Override
500
    		public String toString() { return dsfMIArg.toString(); }	
501
    	}    	
502
503
        // Check if the stopped event can be used to extract the variable value. 
504
        if (execDmc != null && miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT &&
505
            frameDmc.fLevel == 0 && fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null &&
506
            execDmc.equals(fCachedStoppedEvent.getDMContext()) && 
507
            fCachedStoppedEvent.getFrame().getArgs() != null) 
508
        {
509
            if (miVariableDmc.fIndex >= fCachedStoppedEvent.getFrame().getArgs().length) {
510
                rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, -1, "Invalid variable " + miVariableDmc, null));  //$NON-NLS-1$
511
                rm.done();
512
                return;
513
            }
514
515
            rm.setData(new VariableData(fCachedStoppedEvent.getFrame().getArgs()[miVariableDmc.fIndex]));
516
            rm.done();
517
            return;
518
        }
519
520
        if (miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT){
521
	        fMICommandCache.execute(
522
	            new MIStackListArguments(execDmc, true, true),
523
	            new DataRequestMonitor<MIStackListArgumentsInfo>(getExecutor(), rm) { 
524
	                @Override
525
	                protected void handleSuccess() {
526
	                    // Find the correct frame and argument
527
	                    if ( frameDmc.fLevel >= getData().getMIFrames().length ||
528
	                        miVariableDmc.fIndex >= getData().getMIFrames()[frameDmc.fLevel].getArgs().length )
529
	                    {
530
	                        rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable " + miVariableDmc, null));  //$NON-NLS-1$
531
	                        rm.done();
532
	                        return;
533
	                    }
534
	                    
535
	                    // Create the data object.
536
	                    rm.setData(new VariableData(getData().getMIFrames()[frameDmc.fLevel].getArgs()[miVariableDmc.fIndex]));
537
	                    rm.done();
538
	                }});
539
        }//if
540
        if (miVariableDmc.fType == MIVariableDMC.Type.LOCAL){
541
            fMICommandCache.execute(
542
                    new MIStackListLocals(frameDmc, true, true),
543
                    new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), rm) { 
544
                        @Override
545
                        protected void handleSuccess() {
546
   		                    
547
		                    // Create the data object.
548
		                    MIArg[] locals = getData().getLocals();
549
		                    if (locals.length > miVariableDmc.fIndex) {
550
		                    	rm.setData(new VariableData(locals[miVariableDmc.fIndex]));
551
		                    } else {
552
		                        rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable " + miVariableDmc, null));  //$NON-NLS-1$
553
		                    }
554
		                    rm.done();
555
                        }
556
                    });
557
558
        }//if   
559
560
    }
561
562
    private MIVariableDMC[] makeVariableDMCs(IFrameDMContext frame, MIVariableDMC.Type type, int count) {
563
        MIVariableDMC[] variables = new MIVariableDMC[count];
564
        for (int i = 0; i < count; i++) {
565
            variables[i]= new MIVariableDMC(this, frame, type, i);
566
        }
567
        return variables;
568
    }
569
570
    private int findFrameIndex(MIFrame[] frames, int level) {
571
        for (int idx = 0; idx < frames.length; idx++) {
572
            if (frames[idx].getLevel() == level) {
573
                return idx;
574
            }
575
        }
576
        return -1;
577
    }
578
    
579
    
580
    public void getLocals(final IFrameDMContext frameDmc, final DataRequestMonitor<IVariableDMContext[]> rm) {
581
582
        final List<IVariableDMContext> localsList = new ArrayList<IVariableDMContext>();
583
        
584
        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
585
            @Override
586
            protected void handleSuccess() {
587
                rm.setData( localsList.toArray(new IVariableDMContext[localsList.size()]) );
588
                rm.done();
589
            }
590
        };
591
        countingRm.setDoneCount(2);
592
        
593
        getArguments(
594
            frameDmc,
595
            new DataRequestMonitor<IVariableDMContext[]>(getExecutor(), countingRm) { 
596
                @Override
597
                protected void handleSuccess() {
598
                    localsList.addAll( Arrays.asList(getData()) );
599
                    countingRm.done();
600
                }
601
            }); 
602
        
603
	    fMICommandCache.execute(
604
                new MIStackListLocals(frameDmc, true, true),
605
                new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), countingRm) { 
606
                    @Override
607
                    protected void handleSuccess() {
608
                        localsList.addAll( Arrays.asList(
609
                            makeVariableDMCs(frameDmc, MIVariableDMC.Type.LOCAL, getData().getLocals().length)) );
610
                        countingRm.done();
611
                    }
612
                }); 
613
    }
614
615
    public void getStackDepth(IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) {
616
617
		// Make sure we have an execution context (ideally a thread)
618
    	final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
619
	    if (execDmc == null) {
620
            rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
621
            rm.done();
622
            return;
623
        }
624
		
625
	    // Make sure the thread is stopped
626
	    if (!fMIRunControl.isSuspended(execDmc)) {
627
	    	rm.setData(0);
628
	    	rm.done();
629
	    	return;
630
	    }
631
632
	    // Select the proper MI command variant
633
    	MIStackInfoDepth depthCommand = null;
634
    	if (maxDepth > 0) {
635
    		depthCommand = new MIStackInfoDepth(execDmc, true, maxDepth);
636
    	}
637
    	else {
638
    		depthCommand = new MIStackInfoDepth(execDmc);
639
    	}
640
641
    	// And go...
642
    	fMICommandCache.execute(
643
    		depthCommand,
644
    		new DataRequestMonitor<MIStackInfoDepthInfo>(getExecutor(), rm) { 
645
    			@Override
646
   				protected void handleSuccess() {
647
   					rm.setData(getData().getDepth());
648
   					rm.done();
649
   				}
650
    		}); 
651
    }
652
653
    // IServiceEventListener
654
    @DsfServiceEventHandler 
655
    public void eventDispatched(IResumedDMEvent e) {
656
    	fMICommandCache.setContextAvailable(e.getDMContext(), false);
657
        if (e.getReason() != StateChangeReason.STEP) {
658
            fCachedStoppedEvent = null;
659
            fMICommandCache.reset();
660
        }
661
    }
662
    
663
    @DsfServiceEventHandler 
664
    public void eventDispatched(ISuspendedDMEvent e) {
665
    	fMICommandCache.setContextAvailable(e.getDMContext(), true);
666
        fMICommandCache.reset();
667
    }
668
    
669
    @DsfServiceEventHandler 
670
    public void eventDispatched(IMIDMEvent e) {
671
    	MIEvent<? extends IDMContext> miEvent = e.getMIEvent();
672
    	if (miEvent instanceof MIStoppedEvent) {
673
    		fCachedStoppedEvent = (MIStoppedEvent)miEvent;
674
    	}
675
    }
676
677
}
(-)src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java (+254 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 QNX Software Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     QNX Software Systems - Initial API and implementation
10
 *     Ericsson AB			- Modified for DSF Reference Implementation
11
 *******************************************************************************/
12
package org.eclipse.dd.mi.service.command.output;
13
14
import java.math.BigInteger;
15
import java.util.List;
16
import java.util.Vector;
17
import java.util.regex.Matcher;
18
import java.util.regex.Pattern;
19
20
import org.eclipse.dd.dsf.concurrent.Immutable;
21
22
/**
23
 * GDB/MI thread list parsing.
24
 * 
25
 * Example 1:
26
 * 
27
 * -thread-info
28
 * ^done,threads=[
29
 * 	{id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)",
30
 *		frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}],
31
 * 			file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"},
32
 * 			running="0"},
33
 * 	{id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)",
34
 * 		frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}],
35
 * 			file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"},
36
 * 			running="0"}
37
 * 	],current-thread-id="2"
38
 * 
39
40
 * Example 2:
41
 * 
42
 * -thread-info 2
43
 * ^done,threads=[
44
 * 	{id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)",
45
 *		frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}],
46
 * 			file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"},
47
 * 			running="0"}
48
 *  ]
49
 * 
50
 * 
51
 * Example 3 (non-stop):
52
 *
53
 * -thread-info
54
 * ^done,threads=[
55
 * 	{id="2",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1"},
56
 * 	{id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)",
57
 * 		frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}],
58
 * 			file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"},
59
 * 			running="0"}
60
 * 	],current-thread-id="1"
61
 */
62
public class MIThreadInfoInfo extends MIInfo {
63
64
	@Immutable
65
	public class ThreadInfo {
66
67
		final private String      fGdbId;
68
		final private String      fTargetId;
69
		final private String      fOsId;
70
		final private ThreadFrame fTopFrame; 
71
		final private boolean     fIsRunning;
72
		
73
		public ThreadInfo(String gdbId, String targetId, String osId, ThreadFrame topFrame, boolean isRunning) {
74
			fGdbId     = gdbId;
75
			fTargetId  = targetId;
76
			fOsId      = osId;
77
			fTopFrame  = topFrame;
78
			fIsRunning = isRunning;
79
		}
80
81
		public String getGdbId()         { return fGdbId;     }
82
		public String getTargetId()      { return fTargetId;  }
83
		public String getOsId()          { return fOsId;      }
84
		public ThreadFrame getTopFrame() { return fTopFrame;  } 
85
		public boolean isRunning()       { return fIsRunning; }
86
	}
87
88
	@Immutable
89
	public class ThreadFrame {
90
		final private int        fStackLevel;
91
		final private BigInteger fAddress;
92
		final private String     fFunction;
93
		final private ThreadFrameFunctionArgs[] fArgs;
94
		final private String     fFileName;
95
		final private String     fFullName;
96
		final private int        fLineNumber;
97
		
98
		public ThreadFrame(int stackLevel, BigInteger address, String function,
99
				ThreadFrameFunctionArgs[] args,	String file, String fullName, int line)
100
		{
101
			fStackLevel = stackLevel;
102
			fAddress    = address;
103
			fFunction   = function;
104
			fArgs       = args;
105
			fFileName   = file;
106
			fFullName   = fullName;
107
			fLineNumber = line;
108
		}
109
110
		public int        getStackLevel() { return fStackLevel; }
111
		public BigInteger getAddress()    { return fAddress;    }
112
		public String     getFucntion()   { return fFunction;   }
113
		public ThreadFrameFunctionArgs[] getArgs() { return fArgs; }
114
		public String     getFileName()   { return fFileName;   }
115
		public String     getFullName()   { return fFullName;   }
116
		public int        getLineNumber() { return fLineNumber; }
117
	}
118
119
	@Immutable
120
	public class ThreadFrameFunctionArgs {
121
	}
122
123
	private int fCurrentThread = -1;
124
	private List<ThreadInfo> fThreadInfoList = null;
125
	private int[] fThreadList = null;
126
127
	public MIThreadInfoInfo(MIOutput out) {
128
		super(out);
129
		parse();
130
	}
131
132
	public int getCurrentThread() {
133
		return fCurrentThread;
134
	}
135
136
	public List<ThreadInfo> getThreadInfoList() {
137
		return fThreadInfoList;
138
	}
139
140
	public int[] getThreadList() {
141
		return fThreadList;
142
	}
143
144
	// General format:
145
	//		threads=[{...}],current-thread-id="n"
146
	private void parse() {
147
		if (isDone()) {
148
			MIOutput out = getMIOutput();
149
			MIResultRecord rr = out.getMIResultRecord();
150
			if (rr != null) {
151
				MIResult[] results =  rr.getMIResults();
152
				for (int i = 0; i < results.length; i++) {
153
					String var = results[i].getVariable();
154
					if (var.equals("threads")) { //$NON-NLS-1$
155
						MIValue val = results[i].getMIValue();
156
						if (val instanceof MIList) {
157
							parseThreads((MIList) val);
158
						}
159
					}
160
					else if (var.equals("current-thread-id")) { //$NON-NLS-1$
161
						MIValue value = results[i].getMIValue();
162
						if (value instanceof MIConst) {
163
							String str = ((MIConst) value).getCString();
164
							try {
165
								fCurrentThread = Integer.parseInt(str.trim());
166
							} catch (NumberFormatException e) {
167
								fCurrentThread = -1;
168
							}
169
						}
170
					}
171
				}
172
			}
173
		}
174
		if (fThreadInfoList == null) {
175
			fThreadInfoList = new Vector<ThreadInfo>(0);
176
			fThreadList = new int[0];
177
		}
178
	}
179
180
	// General formats:
181
	//		id="n",target-id="Thread 0xb7c8ab90 (LWP 7010)",frame={...},running="0"
182
	//		id="n",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1"
183
	private void parseThreads(MIList list) {
184
		MIValue[] values = list.getMIValues();
185
		fThreadInfoList = new Vector<ThreadInfo>(values.length);
186
		fThreadList = new int[values.length];
187
		
188
		for (int i = 0; i < values.length; i++) {
189
			MITuple value = (MITuple) values[i];
190
			MIResult[] results = value.getMIResults();
191
192
			String gdbId = null;
193
			String targetId = null;
194
			String osId = null;
195
			ThreadFrame topFrame = null;
196
			boolean isRunning = false;
197
198
			for (int j = 0; j < results.length; j++) {
199
				MIResult result = results[j];
200
				String var = result.getVariable();
201
				if (var.equals("id")) { //$NON-NLS-1$
202
					MIValue val = results[j].getMIValue();
203
					if (val instanceof MIConst) {
204
						gdbId = ((MIConst) val).getCString();
205
					}
206
				}
207
				else if (var.equals("target-id")) { //$NON-NLS-1$
208
					MIValue val = results[j].getMIValue();
209
					if (val instanceof MIConst) {
210
						targetId = ((MIConst) val).getCString();
211
						osId = parseOsId(targetId);
212
					}
213
				}
214
				else if (var.equals("frame")) { //$NON-NLS-1$
215
					MIValue val = results[j].getMIValue();
216
					topFrame = parseFrame(val);
217
				}
218
				else if (var.equals("running")) { //$NON-NLS-1$
219
					MIValue val = results[j].getMIValue();
220
					if (val instanceof MIConst) {
221
						String v = ((MIConst) val).getCString();
222
						isRunning = v.equals("1"); //$NON-NLS-1$
223
					}
224
				}
225
			}
226
			
227
			fThreadInfoList.add(new ThreadInfo(gdbId, targetId, osId, topFrame, isRunning));
228
			try {
229
				fThreadList[i] = Integer.parseInt(gdbId);
230
			} catch (NumberFormatException e) {
231
			}
232
		}
233
	}
234
235
	// General format:
236
	// 		"Thread 0xb7c8ab90 (LWP 7010)"
237
	private String parseOsId(String str) {
238
		Pattern pattern = Pattern.compile("(Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)", 0); //$NON-NLS-1$
239
		Matcher matcher = pattern.matcher(str);
240
		if (matcher.find()) {
241
			return matcher.group(4);
242
		}
243
		return null;
244
	}
245
246
	// General format:
247
	// 		level="0",addr="0x08048bba",func="func",args=[...],file="file.cc",fullname="/path/file.cc",line="26"
248
	private ThreadFrame parseFrame(MIValue val) {
249
		// TODO Auto-generated method stub
250
		return null;
251
	}
252
253
}
254
(-)src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java (+42 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 QNX Software Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     QNX Software Systems - Initial API and implementation
10
 *     Ericsson				- Modified for new DSF Reference Implementation
11
 *******************************************************************************/
12
13
package org.eclipse.dd.mi.service.command.commands;
14
15
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
16
import org.eclipse.dd.mi.service.command.output.MIOutput;
17
import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo;
18
19
/**
20
 * 
21
 * -thread-info [ thread-id ]
22
 *
23
 * Reports information about either a specific thread, if [thread-id] is present,
24
 * or about all threads. When printing information about all threads, also reports
25
 * the current thread.
26
 * 
27
 */
28
public class MIThreadInfo extends MICommand<MIThreadInfoInfo> {
29
	
30
	public MIThreadInfo(IContainerDMContext dmc) {
31
		super(dmc, "-thread-info"); //$NON-NLS-1$
32
	}
33
34
	public MIThreadInfo(IContainerDMContext dmc, int threadId) {
35
		super(dmc, "-thread-info", new String[]{ Integer.toString(threadId) }); //$NON-NLS-1$
36
	}
37
38
    @Override
39
    public MIThreadInfoInfo getResult(MIOutput out) {
40
        return new MIThreadInfoInfo(out);
41
    }
42
}
(-)src/org/eclipse/dd/mi/service/MIRunControlNS.java (+897 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *     Ericsson	AB		  - Modified for handling of multiple threads
11
 *******************************************************************************/
12
13
package org.eclipse.dd.mi.service;
14
15
import java.util.HashMap;
16
import java.util.Map;
17
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.core.runtime.Status;
20
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
21
import org.eclipse.dd.dsf.concurrent.Immutable;
22
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
23
import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
24
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
25
import org.eclipse.dd.dsf.datamodel.DMContexts;
26
import org.eclipse.dd.dsf.datamodel.IDMContext;
27
import org.eclipse.dd.dsf.datamodel.IDMEvent;
28
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
29
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
30
import org.eclipse.dd.dsf.service.AbstractDsfService;
31
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
32
import org.eclipse.dd.dsf.service.DsfSession;
33
import org.eclipse.dd.mi.internal.MIPlugin;
34
import org.eclipse.dd.mi.service.command.AbstractMIControl;
35
import org.eclipse.dd.mi.service.command.commands.MIExecContinue;
36
import org.eclipse.dd.mi.service.command.commands.MIExecFinish;
37
import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt;
38
import org.eclipse.dd.mi.service.command.commands.MIExecNext;
39
import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction;
40
import org.eclipse.dd.mi.service.command.commands.MIExecStep;
41
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
42
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
43
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
44
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
45
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
46
import org.eclipse.dd.mi.service.command.events.MIErrorEvent;
47
import org.eclipse.dd.mi.service.command.events.MIEvent;
48
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
49
import org.eclipse.dd.mi.service.command.events.MIRunningEvent;
50
import org.eclipse.dd.mi.service.command.events.MISharedLibEvent;
51
import org.eclipse.dd.mi.service.command.events.MISignalEvent;
52
import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
53
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
54
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
55
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
56
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
57
import org.eclipse.dd.mi.service.command.output.MIInfo;
58
import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo;
59
import org.osgi.framework.BundleContext;
60
61
/**
62
 * Implementation note: This class implements event handlers for the events that
63
 * are generated by this service itself. When the event is dispatched, these
64
 * handlers will be called first, before any of the clients. These handlers
65
 * update the service's internal state information to make them consistent with
66
 * the events being issued. Doing this in the handlers as opposed to when the
67
 * events are generated, guarantees that the state of the service will always be
68
 * consistent with the events. The purpose of this pattern is to allow clients
69
 * that listen to service events and track service state, to be perfectly in
70
 * sync with the service state.
71
 */
72
public class MIRunControlNS extends AbstractDsfService implements IMIRunControl
73
{
74
	// This is an exact copy of the structures in MIRunControl. In an ideal world,
75
	// it would be declared only once in IMIRunControl but this is real life and
76
	// it has to be duplicated for the sake of backward compatibility.
77
	// It sucks and leads to bloated, error-prone code but that's the way it is.
78
	class MIExecutionDMCNS extends AbstractDMContext implements IMIExecutionDMContext
79
	{
80
		/**
81
		 * Integer ID that is used to identify the thread in the GDB/MI protocol.
82
		 */
83
		private final int fThreadId;
84
85
		/**
86
		 * Constructor for the context.  It should not be called directly by clients.
87
		 * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)}
88
		 * to create instances of this context based on the thread ID.
89
		 * <p/>
90
		 * Classes extending {@link MIRunControl} may also extend this class to include
91
		 * additional information in the context.
92
		 * 
93
		 * @param sessionId Session that this context belongs to.
94
		 * @param containerDmc The container that this context belongs to.
95
		 * @param threadId GDB/MI thread identifier.
96
		 */
97
		protected MIExecutionDMCNS(String sessionId, IContainerDMContext containerDmc, int threadId) {
98
			super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
99
			fThreadId = threadId;
100
		}
101
102
		/**
103
		 * Returns the GDB/MI thread identifier of this context.
104
		 * @return
105
		 */
106
		public int getThreadId(){
107
			return fThreadId;
108
		}
109
110
		@Override
111
		public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; }  //$NON-NLS-1$ //$NON-NLS-2$
112
113
		@Override
114
		public boolean equals(Object obj) {
115
			return super.baseEquals(obj) && ((MIExecutionDMCNS)obj).fThreadId == fThreadId;
116
		}
117
118
		@Override
119
		public int hashCode() { return super.baseHashCode() ^ fThreadId; }
120
	}
121
122
	@Immutable
123
	static class ExecutionData implements IExecutionDMData {
124
		private final StateChangeReason fReason;
125
		ExecutionData(StateChangeReason reason) {
126
			fReason = reason;
127
		}
128
		public StateChangeReason getStateChangeReason() { return fReason; }
129
	}
130
131
	/**
132
	 * Base class for events generated by the MI Run Control service.  Most events
133
	 * generated by the MI Run Control service are directly caused by some MI event.
134
	 * Other services may need access to the extended MI data carried in the event.
135
	 * 
136
	 * @param <V> DMC that this event refers to
137
	 * @param <T> MIInfo object that is the direct cause of this event
138
	 * @see MIRunControl
139
	 */
140
	@Immutable
141
	static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V>
142
	implements IDMEvent<V>, IMIDMEvent
143
	{
144
		final private T fMIInfo;
145
		public RunControlEvent(V dmc, T miInfo) {
146
			super(dmc);
147
			fMIInfo = miInfo;
148
		}
149
150
		public T getMIEvent() { return fMIInfo; }
151
	}
152
153
	/**
154
	 * Indicates that the given thread has been suspended.
155
	 */
156
	@Immutable
157
	static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
158
	implements ISuspendedDMEvent
159
	{
160
		SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
161
			super(ctx, miInfo);
162
		}
163
164
		public StateChangeReason getReason() {
165
			if (getMIEvent() instanceof MIBreakpointHitEvent) {
166
				return StateChangeReason.BREAKPOINT;
167
			} else if (getMIEvent() instanceof MISteppingRangeEvent) {
168
				return StateChangeReason.STEP;
169
			} else if (getMIEvent() instanceof MISharedLibEvent) {
170
				return StateChangeReason.SHAREDLIB;
171
			}else if (getMIEvent() instanceof MISignalEvent) {
172
				return StateChangeReason.SIGNAL;
173
			}else if (getMIEvent() instanceof MIWatchpointTriggerEvent) {
174
				return StateChangeReason.WATCHPOINT;
175
			}else if (getMIEvent() instanceof MIErrorEvent) {
176
				return StateChangeReason.ERROR;
177
			}else {
178
				return StateChangeReason.USER_REQUEST;
179
			}
180
		}
181
	}
182
183
	@Immutable
184
	static class ContainerSuspendedEvent extends SuspendedEvent
185
	implements IContainerSuspendedDMEvent
186
	{
187
		final IExecutionDMContext[] triggeringDmcs;
188
		ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
189
			super(containerDmc, miInfo);
190
			this.triggeringDmcs = triggeringDmc != null
191
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
192
		}
193
194
		public IExecutionDMContext[] getTriggeringContexts() {
195
			return triggeringDmcs;
196
		}
197
	}
198
199
	@Immutable
200
	static class ThreadSuspendedEvent extends SuspendedEvent
201
	{
202
		ThreadSuspendedEvent(IExecutionDMContext executionDmc, MIStoppedEvent miInfo) {
203
			super(executionDmc, miInfo);
204
		}
205
	}
206
207
	@Immutable
208
	static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
209
	implements IResumedDMEvent
210
	{
211
		ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
212
			super(ctx, miInfo);
213
		}
214
215
		public StateChangeReason getReason() {
216
			switch(getMIEvent().getType()) {
217
			case MIRunningEvent.CONTINUE:
218
				return StateChangeReason.USER_REQUEST;
219
			case MIRunningEvent.NEXT:
220
			case MIRunningEvent.NEXTI:
221
				return StateChangeReason.STEP;
222
			case MIRunningEvent.STEP:
223
			case MIRunningEvent.STEPI:
224
				return StateChangeReason.STEP;
225
			case MIRunningEvent.FINISH:
226
				return StateChangeReason.STEP;
227
			case MIRunningEvent.UNTIL:
228
			case MIRunningEvent.RETURN:
229
				break;
230
			}
231
			return StateChangeReason.UNKNOWN;
232
		}
233
	}
234
235
	@Immutable
236
	static class ContainerResumedEvent extends ResumedEvent
237
	implements IContainerResumedDMEvent
238
	{
239
		final IExecutionDMContext[] triggeringDmcs;
240
241
		ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
242
			super(containerDmc, miInfo);
243
			this.triggeringDmcs = triggeringDmc != null
244
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
245
		}
246
247
		public IExecutionDMContext[] getTriggeringContexts() {
248
			return triggeringDmcs;
249
		}
250
	}
251
252
	@Immutable
253
	static class ThreadResumedEvent extends ResumedEvent
254
	{
255
		ThreadResumedEvent(IExecutionDMContext executionDmc, MIRunningEvent miInfo) {
256
			super(executionDmc, miInfo);
257
		}
258
	}
259
260
	@Immutable
261
	static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
262
	implements IStartedDMEvent
263
	{
264
		StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
265
			super(executionDmc, miInfo);
266
		}
267
	}
268
269
	@Immutable
270
	static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
271
	implements IExitedDMEvent
272
	{
273
		ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
274
			super(executionDmc, miInfo);
275
		}
276
	}
277
278
	protected class MIThreadRunState {
279
		// State flags
280
		boolean fSuspended = false;
281
		boolean fResumePending = false;
282
		boolean fStepping = false;
283
		StateChangeReason fStateChangeReason;
284
	}
285
286
	///////////////////////////////////////////////////////////////////////////
287
	// MIRunControlNS
288
	///////////////////////////////////////////////////////////////////////////
289
290
	private AbstractMIControl fConnection;
291
292
	// The command cache applies only for the thread-info command at the
293
	// container (process) level and is *always* available in non-stop mode.
294
	// The only thing to do is to reset it every time a thread is created/
295
	// terminated.
296
	private CommandCache fMICommandCache;
297
298
	private boolean fTerminated = false;
299
300
	// ThreadStates indexed by the execution context
301
	protected Map<IMIExecutionDMContext, MIThreadRunState> fThreadRunStates = new HashMap<IMIExecutionDMContext, MIThreadRunState>();
302
303
	///////////////////////////////////////////////////////////////////////////
304
	// Initialization and shutdown
305
	///////////////////////////////////////////////////////////////////////////
306
307
	public MIRunControlNS(DsfSession session) {
308
		super(session);
309
	}
310
311
	@Override
312
	public void initialize(final RequestMonitor rm) {
313
		super.initialize(new RequestMonitor(getExecutor(), rm) {
314
			@Override
315
			protected void handleSuccess() {
316
				doInitialize(rm);
317
			}
318
		});
319
	}
320
321
	private void doInitialize(final RequestMonitor rm) {
322
		fConnection = getServicesTracker().getService(AbstractMIControl.class);
323
        fMICommandCache = new CommandCache(getSession(), fConnection);
324
        fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
325
		getSession().addServiceEventListener(this, null);
326
		rm.done();
327
	}
328
329
	@Override
330
	public void shutdown(final RequestMonitor rm) {
331
		getSession().removeServiceEventListener(this);
332
        fMICommandCache.reset();
333
		super.shutdown(rm);
334
	}
335
336
	///////////////////////////////////////////////////////////////////////////
337
	// AbstractDsfService
338
	///////////////////////////////////////////////////////////////////////////
339
340
	@Override
341
	protected BundleContext getBundleContext() {
342
		return MIPlugin.getBundleContext();
343
	}
344
345
	///////////////////////////////////////////////////////////////////////////
346
	// IDMService
347
	///////////////////////////////////////////////////////////////////////////
348
349
	@SuppressWarnings("unchecked")
350
	public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
351
		if (dmc instanceof IExecutionDMContext) {
352
			getExecutionData((IExecutionDMContext) dmc, (DataRequestMonitor<IExecutionDMData>) rm);
353
		} else {
354
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
355
			rm.done();
356
		}
357
	}
358
359
	///////////////////////////////////////////////////////////////////////////
360
	// IRunControl
361
	///////////////////////////////////////////////////////////////////////////
362
363
	// ------------------------------------------------------------------------
364
	// Suspend
365
	// ------------------------------------------------------------------------
366
367
	public boolean isSuspended(IExecutionDMContext context) {
368
369
		// Thread case
370
		if (context instanceof MIExecutionDMCNS) {
371
			MIThreadRunState threadState = fThreadRunStates.get(context);
372
			return (threadState == null) ? false : !fTerminated && threadState.fSuspended;
373
		}
374
375
		// Container case
376
		if (context instanceof IContainerDMContext) {
377
			boolean isSuspended = false;
378
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
379
				if (DMContexts.isAncestorOf(threadContext, context)) {
380
					isSuspended |= isSuspended(threadContext);
381
				}
382
			}
383
			return isSuspended;
384
		}
385
386
		// Default case
387
		return false;
388
	}
389
390
	public void canSuspend(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) {
391
392
		// Thread case
393
		if (context instanceof MIExecutionDMCNS) {
394
			rm.setData(doCanSuspend(context));
395
			rm.done();
396
			return;
397
		}
398
399
		// Container case
400
		if (context instanceof IContainerDMContext) {
401
			boolean canSuspend = false;
402
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
403
				if (DMContexts.isAncestorOf(threadContext, context)) {
404
					canSuspend |= doCanSuspend(threadContext);
405
				}
406
			}
407
			rm.setData(canSuspend);
408
			rm.done();
409
			return;
410
		}
411
412
		// Default case
413
		rm.setData(false);
414
		rm.done();
415
	}
416
417
	private boolean doCanSuspend(IExecutionDMContext context) {
418
		MIThreadRunState threadState = fThreadRunStates.get(context);
419
		return (threadState == null) ? false : !fTerminated && !threadState.fSuspended;
420
	}
421
422
	public void suspend(IExecutionDMContext context, final RequestMonitor rm) {
423
424
		assert context != null;
425
426
		// Thread case
427
		IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
428
		if (thread != null) {
429
			doSuspendThread(thread, rm);
430
			return;
431
		}
432
433
		// Container case
434
		IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class);
435
		if (container != null) {
436
			doSuspendContainer(container, rm);
437
			return;
438
		}
439
440
		// Default case
441
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
442
		rm.done();
443
	}
444
445
	private void doSuspendThread(IMIExecutionDMContext context, final RequestMonitor rm) {
446
447
		if (!doCanSuspend(context)) {
448
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
449
				"Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$
450
			rm.done();
451
			return;
452
		}
453
454
		MIExecInterrupt cmd = new MIExecInterrupt(context, true);
455
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
456
	}
457
458
	private void doSuspendContainer(IExecutionDMContext context, final RequestMonitor rm) {
459
		MIExecInterrupt cmd = new MIExecInterrupt(context, true);
460
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
461
	}
462
463
	// ------------------------------------------------------------------------
464
	// Resume
465
	// ------------------------------------------------------------------------
466
467
	public void canResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) {
468
469
		// Thread case
470
		if (context instanceof MIExecutionDMCNS) {
471
			rm.setData(doCanResume(context));
472
			rm.done();
473
			return;
474
		}
475
476
		// Container case
477
		if (context instanceof IContainerDMContext) {
478
			boolean canSuspend = false;
479
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
480
				if (DMContexts.isAncestorOf(threadContext, context)) {
481
					canSuspend |= doCanResume(threadContext);
482
				}
483
			}
484
			rm.setData(canSuspend);
485
			rm.done();
486
			return;
487
		}
488
489
		// Default case
490
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
491
		rm.done();
492
	}
493
494
	private boolean doCanResume(IExecutionDMContext context) {
495
		MIThreadRunState threadState = fThreadRunStates.get(context);
496
		return (threadState == null) ? false : !fTerminated && threadState.fSuspended && !threadState.fResumePending;
497
	}
498
499
	public void resume(IExecutionDMContext context, final RequestMonitor rm) {
500
501
		assert context != null;
502
503
		// Thread case
504
		IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
505
		if (thread != null) {
506
			doResumeThread(thread, rm);
507
			return;
508
		}
509
510
		// Container case
511
		IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class);
512
		if (container != null) {
513
			doResumeContainer(container, rm);
514
			return;
515
		}
516
517
		// Default case
518
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
519
		rm.done();
520
	}
521
522
	private void doResumeThread(IMIExecutionDMContext context, final RequestMonitor rm) {
523
524
		if (!doCanResume(context)) {
525
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
526
				"Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$
527
			rm.done();
528
			return;
529
		}
530
531
		MIThreadRunState threadState = fThreadRunStates.get(context);
532
		if (threadState == null) {
533
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
534
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
535
			rm.done();
536
			return;
537
		}
538
		threadState.fResumePending = true;
539
540
		MIExecContinue cmd = new MIExecContinue(context, context.getThreadId());
541
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
542
	}
543
544
	private void doResumeContainer(IContainerDMContext context, final RequestMonitor rm) {
545
		MIExecContinue cmd = new MIExecContinue(context, false);
546
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
547
	}
548
549
	// ------------------------------------------------------------------------
550
	// Step
551
	// ------------------------------------------------------------------------
552
553
	public boolean isStepping(IExecutionDMContext context) {
554
555
		// If it's a thread, just look it up
556
		if (context instanceof MIExecutionDMCNS) {
557
			MIThreadRunState threadState = fThreadRunStates.get(context);
558
			return (threadState == null) ? false : !fTerminated && threadState.fStepping;
559
		}
560
561
		// Default case
562
		return false;
563
	}
564
565
	public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm) {
566
567
		// If it's a thread, just look it up
568
		if (context instanceof MIExecutionDMCNS) {
569
			canResume(context, rm);
570
			return;
571
		}
572
573
		// If it's a container, then we don't want to step it
574
		rm.setData(false);
575
		rm.done();
576
	}
577
578
	public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) {
579
580
		assert context != null;
581
582
		IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
583
		if (dmc == null) {
584
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
585
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
586
			rm.done();
587
			return;
588
		}
589
590
		if (!doCanResume(context)) {
591
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
592
				"Cannot resume context", null)); //$NON-NLS-1$
593
			rm.done();
594
			return;
595
		}
596
597
		MIThreadRunState threadState = fThreadRunStates.get(context);
598
		if (threadState == null) {
599
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
600
				"Given context: " + context + " can't be found.", null)); //$NON-NLS-1$ //$NON-NLS-2$
601
			rm.done();
602
			return;
603
		}
604
605
		threadState.fResumePending = true;
606
		threadState.fStepping = true;
607
608
		switch (stepType) {
609
		case STEP_INTO:
610
			fConnection.queueCommand(new MIExecStep(dmc, true),
611
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
612
			break;
613
		case STEP_OVER:
614
			fConnection.queueCommand(new MIExecNext(dmc, true),
615
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
616
			break;
617
		case STEP_RETURN:
618
			// The -exec-finish command operates on the selected stack frame, but here we always
619
			// want it to operate on the stop stack frame. So we manually create a top-frame
620
			// context to use with the MI command.
621
			// We get a local instance of the stack service because the stack service can be shut
622
			// down before the run control service is shut down. So it is possible for the
623
			// getService() request below to return null.
624
			MIStack stackService = getServicesTracker().getService(MIStack.class);
625
			if (stackService != null) {
626
				IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0);
627
				fConnection.queueCommand(new MIExecFinish(topFrameDmc),
628
						new DataRequestMonitor<MIInfo>(getExecutor(), rm));
629
			} else {
630
				rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
631
						"Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$
632
				rm.done();
633
			}
634
			break;
635
		case INSTRUCTION_STEP_INTO:
636
			fConnection.queueCommand(new MIExecStepInstruction(dmc, true),
637
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
638
			break;
639
		case INSTRUCTION_STEP_OVER:
640
			fConnection.queueCommand(new MIExecNextInstruction(dmc, true),
641
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
642
			break;
643
		default:
644
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,
645
					INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$
646
			rm.done();
647
		}
648
	}
649
650
	// ------------------------------------------------------------------------
651
	// Run to line
652
	// ------------------------------------------------------------------------
653
654
	// Later add support for Address and function.
655
	// skipBreakpoints is not used at the moment. Implement later
656
	public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm) {
657
658
		assert context != null;
659
660
		IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
661
		if (dmc == null) {
662
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
663
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
664
			rm.done();
665
			return;
666
		}
667
668
		if (!doCanResume(context)) {
669
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
670
				"Cannot resume context", null)); //$NON-NLS-1$
671
			rm.done();
672
			return;
673
		}
674
675
		MIThreadRunState threadState = fThreadRunStates.get(context);
676
		if (threadState == null) {
677
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
678
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
679
			rm.done();
680
			return;
681
		}
682
683
		threadState.fResumePending = true;
684
		fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$
685
				new DataRequestMonitor<MIInfo>(getExecutor(), rm));
686
	}
687
688
	// ------------------------------------------------------------------------
689
	// Support functions
690
	// ------------------------------------------------------------------------
691
692
	public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
693
		fMICommandCache.execute(new MIThreadListIds(containerDmc),
694
				new DataRequestMonitor<MIThreadListIdsInfo>(getExecutor(), rm) {
695
					@Override
696
					protected void handleSuccess() {
697
						rm.setData(makeExecutionDMCs(containerDmc, getData()));
698
						rm.done();
699
					}
700
				});
701
	}
702
703
	private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerCtx, MIThreadListIdsInfo info) {
704
		IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length];
705
		for (int i = 0; i < info.getThreadIds().length; i++) {
706
			executionDmcs[i] = createMIExecutionContext(containerCtx, info.getThreadIds()[i]);
707
		}
708
		return executionDmcs;
709
	}
710
711
	public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) {
712
		MIThreadRunState threadState = fThreadRunStates.get(dmc);
713
		if (threadState == null) {
714
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,INVALID_HANDLE,
715
				"Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
716
			rm.done();
717
			return;
718
		}
719
720
		if (dmc instanceof IMIExecutionDMContext) {
721
			rm.setData(new ExecutionData(threadState.fSuspended ? threadState.fStateChangeReason : null));
722
		} else {
723
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE,
724
				"Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
725
		}
726
		rm.done();
727
	}
728
729
	///////////////////////////////////////////////////////////////////////////
730
	// IMIRunControl
731
	///////////////////////////////////////////////////////////////////////////
732
733
	public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) {
734
		return new MIExecutionDMCNS(getSession().getId(), container, threadId);
735
	}
736
737
	///////////////////////////////////////////////////////////////////////////
738
	// IMIRunControl
739
	///////////////////////////////////////////////////////////////////////////
740
741
	public CommandCache getCache() {
742
		 return fMICommandCache;
743
	}
744
745
	protected AbstractMIControl getConnection() {
746
		 return fConnection;
747
	}
748
749
	///////////////////////////////////////////////////////////////////////////
750
	// Event handlers
751
	///////////////////////////////////////////////////////////////////////////
752
753
	@DsfServiceEventHandler
754
	public void eventDispatched(final MIRunningEvent e) {
755
756
		IDMEvent<?> event = null;
757
758
		// If it's not an execution context (what else could it be?!?), just propagate it 
759
		IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
760
		if (executionDmc == null) {
761
			event = new ResumedEvent(e.getDMContext(), e);
762
			getSession().dispatchEvent(event, getProperties());
763
			return;
764
		}
765
766
		// It's a thread execution context (since we are in non-stop mode)
767
		event = new ThreadResumedEvent(e.getDMContext(), e);
768
		updateThreadState(executionDmc, (ThreadResumedEvent) event);
769
		getSession().dispatchEvent(event, getProperties());
770
		fMICommandCache.reset();
771
772
        // Find the container context, which is used in multi-threaded debugging.
773
        IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class);
774
        if (containerDmc != null) {
775
        	IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null;
776
            event = new ContainerResumedEvent(containerDmc, e, triggeringCtx);
777
            getSession().dispatchEvent(event, getProperties());
778
        }
779
	}
780
781
	private void updateThreadState(IMIExecutionDMContext context, ThreadResumedEvent event) {
782
		StateChangeReason reason = event.getReason();
783
		boolean isStepping = reason.equals(StateChangeReason.STEP);
784
		MIThreadRunState threadState = fThreadRunStates.get(context);
785
		if (threadState == null) {
786
			threadState = new MIThreadRunState();
787
			fThreadRunStates.put(context, threadState);
788
		}
789
		threadState.fSuspended = false;
790
		threadState.fResumePending = false;
791
		threadState.fStateChangeReason = reason;
792
		threadState.fStepping = isStepping;
793
	}
794
795
	@DsfServiceEventHandler
796
	public void eventDispatched(final MIStoppedEvent e) {
797
798
		IDMEvent<?> event = null;
799
800
		// If it's not an execution context (what else could it be?!?), just propagate it 
801
		IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
802
		if (executionDmc == null) {
803
			event = new SuspendedEvent(e.getDMContext(), e);
804
			getSession().dispatchEvent(event, getProperties());
805
			return;
806
		}
807
808
		// It's a thread execution context (since we are in non-stop mode)
809
		event = new ThreadSuspendedEvent(e.getDMContext(), e);
810
		updateThreadState(executionDmc, (ThreadSuspendedEvent) event);
811
		getSession().dispatchEvent(event, getProperties());
812
		fMICommandCache.reset();
813
814
		// Find the container context, which is used in multi-threaded debugging.
815
        IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class);
816
        if (containerDmc != null) {
817
        	IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null;
818
            event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx);
819
            getSession().dispatchEvent(event, getProperties());
820
        }
821
	}
822
823
	private void updateThreadState(IMIExecutionDMContext context, ThreadSuspendedEvent event) {
824
		StateChangeReason reason = event.getReason();
825
		MIThreadRunState threadState = fThreadRunStates.get(context);
826
		if (threadState == null) {
827
			threadState = new MIThreadRunState();
828
			fThreadRunStates.put(context, threadState);
829
		}
830
		threadState.fSuspended = true;
831
		threadState.fResumePending = false;
832
		threadState.fStepping = false;
833
		threadState.fStateChangeReason = reason;
834
	}
835
836
	@DsfServiceEventHandler
837
	public void eventDispatched(final MIThreadCreatedEvent e) {
838
		IContainerDMContext containerDmc = e.getDMContext();
839
		IMIExecutionDMContext executionCtx = null;
840
		if (e.getId() != -1) {
841
			executionCtx = createMIExecutionContext(containerDmc, e.getId());
842
			if (fThreadRunStates.get(executionCtx) == null) {
843
				fThreadRunStates.put(executionCtx, new MIThreadRunState());
844
			}
845
		}
846
		getSession().dispatchEvent(new StartedDMEvent(executionCtx, e),	getProperties());
847
	}
848
849
	@DsfServiceEventHandler
850
	public void eventDispatched(final MIThreadExitEvent e) {
851
		IContainerDMContext containerDmc = e.getDMContext();
852
		IMIExecutionDMContext executionCtx = null;
853
		if (e.getId() != -1) {
854
			executionCtx = createMIExecutionContext(containerDmc, e.getId());
855
			fThreadRunStates.remove(executionCtx);
856
		}
857
		getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties());
858
	}
859
860
	@DsfServiceEventHandler
861
	public void eventDispatched(ThreadResumedEvent e) {
862
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
863
		if (context == null) {
864
			return;
865
		}
866
	}
867
868
	@DsfServiceEventHandler
869
	public void eventDispatched(ThreadSuspendedEvent e) {
870
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
871
		if (context == null) {
872
			return;
873
		}
874
	}
875
876
	@DsfServiceEventHandler
877
	public void eventDispatched(ContainerResumedEvent e) {
878
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
879
		if (context == null) {
880
			return;
881
		}
882
	}
883
884
	@DsfServiceEventHandler
885
	public void eventDispatched(ContainerSuspendedEvent e) {
886
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
887
		if (context == null) {
888
			return;
889
		}
890
	}
891
892
	@DsfServiceEventHandler
893
	public void eventDispatched(MIGDBExitEvent e) {
894
		fTerminated = true;
895
	}
896
897
}

Return to bug 237556