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/gdb/internal/provisional/service/GDBRunControl.java (-41 / +4 lines)
Lines 29-80 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
     * Implement a custom execution data for threads in order to provide additional 
41
     * information.  This object can be made separate from IExecutionDMData after
42
     * the deprecated method: IDMService.getModelData() is no longer used.  
43
     */
44
    public static class GDBThreadData {
45
        private final String fId;
46
        private final String fName;
47
48
        GDBThreadData(String id, String name) {
49
            fId = id;
50
            fName = name;
51
        }
52
        
53
        public String getName() {
54
            return fName; 
55
        }
56
        public String getId() { return fId; } 
57
58
        public boolean isDebuggerAttached() { return true; }
59
    }
60
40
61
    /**
62
     * Implement a custom execution data the process in order to provide additional 
63
     * information.  This object can be made separate from IExecutionDMData after
64
     * the deprecated method: IDMService.getModelData() is no longer used.  
65
     */
66
    public static class GDBProcessData {
67
        private final String fName;
68
        
69
        GDBProcessData(String name) {
70
            fName = name;
71
        }
72
        
73
        public String getName() {
74
            return fName;
75
        }
76
    }
77
    
78
    private GDBControl fGdb;
41
    private GDBControl fGdb;
79
    
42
    
80
	// Record list of execution contexts
43
	// Record list of execution contexts
Lines 98-104 Link Here
98
    private void doInitialize(final RequestMonitor requestMonitor) {
61
    private void doInitialize(final RequestMonitor requestMonitor) {
99
    	
62
    	
100
        fGdb = getServicesTracker().getService(GDBControl.class);
63
        fGdb = getServicesTracker().getService(GDBControl.class);
101
        register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>());
64
        register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName(), IGDBRunControl.class.getName()}, new Hashtable<String,String>());
102
65
103
        requestMonitor.done();
66
        requestMonitor.done();
104
    }
67
    }
Lines 168-174 Link Here
168
	}
131
	}
169
132
170
    private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, CLIInfoThreadsInfo info){
133
    private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, CLIInfoThreadsInfo info){
171
        for (CLIInfoThreadsInfo.ThreadInfo thread : info.getThreadInfo()) {
134
        for (CLIInfoThreadsInfo.CLIThreadInfo thread : info.getThreadInfo()) {
172
            if(Integer.parseInt(thread.getId()) == dmc.getThreadId()){
135
            if(Integer.parseInt(thread.getId()) == dmc.getThreadId()){
173
                //fMapThreadIds.put(thread.getId(), String.valueOf(dmc.getId()));
136
                //fMapThreadIds.put(thread.getId(), String.valueOf(dmc.getId()));
174
                return new GDBThreadData(thread.getOsId(), thread.getName());       
137
                return new GDBThreadData(thread.getOsId(), thread.getName());       
(-)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/IGDBRunControl.java (+70 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
	/**
30
     * Implement a custom execution data for threads in order to provide additional 
31
     * information.  This object can be made separate from IExecutionDMData after
32
     * the deprecated method: IDMService.getModelData() is no longer used.  
33
     */
34
    public static class GDBThreadData {
35
        private final String fId;
36
        private final String fName;
37
38
        GDBThreadData(String id, String name) {
39
            fId = id;
40
            fName = name;
41
        }
42
        
43
        public String getName() {
44
            return fName; 
45
        }
46
        public String getId() { return fId; } 
47
48
        public boolean isDebuggerAttached() { return true; }
49
    }
50
51
    /**
52
     * Implement a custom execution data the process in order to provide additional 
53
     * information.  This object can be made separate from IExecutionDMData after
54
     * the deprecated method: IDMService.getModelData() is no longer used.  
55
     */
56
    public static class GDBProcessData {
57
        private final String fName;
58
        
59
        GDBProcessData(String name) {
60
            fName = name;
61
        }
62
        
63
        public String getName() {
64
            return fName;
65
        }
66
    }
67
68
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<GDBProcessData> rm);
69
    public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<GDBThreadData> dataRequestMonitor);
70
}
(-)src/org/eclipse/dd/gdb/internal/provisional/service/GdbDebugServicesFactoryNS.java (+26 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.service.DsfSession;
15
16
public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory {
17
18
	public GdbDebugServicesFactoryNS(String version) {
19
		super(version);
20
	}
21
		
22
	@Override
23
	protected IRunControl createRunControlService(DsfSession session) {
24
		return new GDBRunControlNS(session);
25
	}
26
}
(-)src/org/eclipse/dd/gdb/internal/provisional/service/GDBRunControlNS.java (+90 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
    private GDBControl fGdb;
34
    
35
    public GDBRunControlNS(DsfSession session) {
36
        super(session);
37
    }
38
    
39
    @Override
40
    public void initialize(final RequestMonitor requestMonitor) {
41
        super.initialize(
42
            new RequestMonitor(getExecutor(), requestMonitor) { 
43
                @Override
44
                public void handleSuccess() {
45
                    doInitialize(requestMonitor);
46
                }});
47
    }
48
49
    private void doInitialize(final RequestMonitor requestMonitor) {
50
51
		fGdb = getServicesTracker().getService(GDBControl.class);
52
        register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName(), IGDBRunControl.class.getName()}, new Hashtable<String,String>());
53
54
        requestMonitor.done();
55
    }
56
57
    @Override
58
    public void shutdown(final RequestMonitor requestMonitor) {
59
        unregister();
60
        super.shutdown(requestMonitor);
61
    }
62
63
	public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<GDBProcessData> rm) {
64
        rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
65
        rm.done();
66
	}
67
	
68
	public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<GDBThreadData> rm) {
69
        IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
70
        assert containerDmc != null;
71
        getCache().execute(new MIThreadInfo(containerDmc),
72
                new DataRequestMonitor<MIThreadInfoInfo>(getExecutor(), rm) {
73
                    @Override
74
                    protected void handleSuccess() {
75
                        rm.setData(createThreadInfo(execDmc, getData()));
76
                        rm.done();
77
                    }
78
                });
79
	}
80
81
	private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, MIThreadInfoInfo info){
82
		for (MIThreadInfoInfo.ThreadInfo thread : info.getThreadInfoList()) {
83
			if (Integer.parseInt(thread.getGdbId()) == dmc.getThreadId()){
84
				return new GDBThreadData(thread.getOsId(), "");        //$NON-NLS-1$
85
			}
86
		}
87
		return  new GDBThreadData("", "");  //$NON-NLS-1$ //$NON-NLS-2$
88
	}
89
90
}
(-)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 / +1 lines)
Lines 30-41 Link Here
30
{
30
{
31
	
31
	
32
    public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) {
32
    public MIStackListLocals(IFrameDMContext frameCtx, boolean printValues) {
33
        super(frameCtx, "-stack-list-locals"); //$NON-NLS-1$
33
        super(frameCtx, "-stack-list-locals", new String[] { printValues ? "1" : "0"} ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
34
        if (printValues) {
35
            setParameters(new String[]{"1"}); //$NON-NLS-1$
36
        } else {
37
            setParameters(new String[]{"0"}); //$NON-NLS-1$
38
        }
39
    }
34
    }
40
    
35
    
41
    @Override
36
    @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 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
(-)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 / +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-continue
21
 *      -exec-continue [--thread <tid>]
21
 * 
22
 * 
22
 *   Asynchronous command.  Resumes the execution of the inferior program
23
 *   Asynchronous command.  Resumes the execution of the inferior program
23
 *   until a breakpoint is encountered, or until the inferior exits.
24
 *   until a breakpoint is encountered, or until the inferior exits.
Lines 26-31 Link Here
26
public class MIExecContinue extends MICommand<MIInfo> 
27
public class MIExecContinue extends MICommand<MIInfo> 
27
{
28
{
28
    public MIExecContinue(IExecutionDMContext dmc) {
29
    public MIExecContinue(IExecutionDMContext dmc) {
30
        this(dmc, false);
31
    }
32
33
    public MIExecContinue(IExecutionDMContext dmc, boolean allThreads) {
34
        super(dmc, "-exec-continue"); //$NON-NLS-1$
35
        if (allThreads) {
36
        	setParameters(new String[] { "--all" }); //$NON-NLS-1$
37
        }
38
    }
39
40
    public MIExecContinue(IMIExecutionDMContext dmc, boolean setThread) {
29
        super(dmc, "-exec-continue"); //$NON-NLS-1$
41
        super(dmc, "-exec-continue"); //$NON-NLS-1$
42
        if (setThread) {
43
        	setParameters(new String[] { "--thread", Integer.toString(dmc.getThreadId()) }); //$NON-NLS-1$
44
        }
30
    }
45
    }
31
}
46
}
(-)src/org/eclipse/dd/mi/service/command/commands/MIStackListFrames.java (-2 / +1 lines)
Lines 58-65 Link Here
58
    }
58
    }
59
    
59
    
60
    public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) {
60
    public MIStackListFrames(IMIExecutionDMContext execDmc, int low, int high) {
61
        super(execDmc, "-stack-list-frames", new String[]{Integer.toString(low), //$NON-NLS-1$
61
        super(execDmc, "-stack-list-frames", new String[] { Integer.toString(low), Integer.toString(high) } ); //$NON-NLS-1$
62
        										 Integer.toString(high)});
63
    }
62
    }
64
    
63
    
65
    @Override
64
    @Override
(-)src/org/eclipse/dd/mi/service/MIBreakpointsManager.java (-1 / +1 lines)
Lines 67-77 Link Here
67
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
67
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
68
import org.eclipse.dd.dsf.service.DsfSession;
68
import org.eclipse.dd.dsf.service.DsfSession;
69
import org.eclipse.dd.mi.internal.MIPlugin;
69
import org.eclipse.dd.mi.internal.MIPlugin;
70
import org.eclipse.dd.mi.service.IMIRunControl.MIExecutionDMC;
70
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointAddedEvent;
71
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointAddedEvent;
71
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent;
72
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointRemovedEvent;
72
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent;
73
import org.eclipse.dd.mi.service.MIBreakpoints.BreakpointUpdatedEvent;
73
import org.eclipse.dd.mi.service.MIBreakpoints.MIBreakpointDMContext;
74
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;
75
import org.eclipse.dd.mi.service.breakpoint.actions.BreakpointActionAdapter;
76
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
76
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
77
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
77
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
(-)src/org/eclipse/dd/mi/service/MIMemory.java (-2 / +2 lines)
Lines 70-76 Link Here
70
    }
70
    }
71
71
72
    @SuppressWarnings("unused")
72
    @SuppressWarnings("unused")
73
	private MIRunControl fRunControl;
73
	private IMIRunControl fRunControl;
74
    private MIMemoryCache fMemoryCache;
74
    private MIMemoryCache fMemoryCache;
75
75
76
	/**
76
	/**
Lines 114-120 Link Here
114
    	register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
114
    	register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
115
115
116
    	// Get the RunControl so we can retrieve the current Execution context
116
    	// Get the RunControl so we can retrieve the current Execution context
117
    	fRunControl = getServicesTracker().getService(MIRunControl.class);
117
    	fRunControl = getServicesTracker().getService(IMIRunControl.class);
118
118
119
    	// Create the memory requests cache
119
    	// Create the memory requests cache
120
    	fMemoryCache = new MIMemoryCache();
120
    	fMemoryCache = new MIMemoryCache();
(-)src/org/eclipse/dd/mi/service/MIRunControl.java (-203 / +3 lines)
Lines 14-27 Link Here
14
import org.eclipse.core.runtime.IStatus;
14
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.core.runtime.Status;
15
import org.eclipse.core.runtime.Status;
16
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
16
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
17
import org.eclipse.dd.dsf.concurrent.Immutable;
18
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
17
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
19
import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
20
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
21
import org.eclipse.dd.dsf.datamodel.DMContexts;
18
import org.eclipse.dd.dsf.datamodel.DMContexts;
22
import org.eclipse.dd.dsf.datamodel.IDMContext;
19
import org.eclipse.dd.dsf.datamodel.IDMContext;
23
import org.eclipse.dd.dsf.datamodel.IDMEvent;
20
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;
21
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
26
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
22
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
27
import org.eclipse.dd.dsf.service.AbstractDsfService;
23
import org.eclipse.dd.dsf.service.AbstractDsfService;
Lines 38-56 Link Here
38
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
34
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
39
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
35
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
40
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
36
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
41
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
42
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
43
import org.eclipse.dd.mi.service.command.events.MIErrorEvent;
44
import org.eclipse.dd.mi.service.command.events.MIEvent;
45
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
37
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
46
import org.eclipse.dd.mi.service.command.events.MIRunningEvent;
38
import org.eclipse.dd.mi.service.command.events.MIRunningEvent;
47
import org.eclipse.dd.mi.service.command.events.MISharedLibEvent;
48
import org.eclipse.dd.mi.service.command.events.MISignalEvent;
49
import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
50
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
39
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
51
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
40
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
52
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
41
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
53
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
54
import org.eclipse.dd.mi.service.command.output.MIInfo;
42
import org.eclipse.dd.mi.service.command.output.MIInfo;
55
import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo;
43
import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo;
56
import org.osgi.framework.BundleContext;
44
import org.osgi.framework.BundleContext;
Lines 71-267 Link Here
71
 * events and track service state, to be perfectly in sync with the service
59
 * events and track service state, to be perfectly in sync with the service
72
 * state.
60
 * state.
73
 */
61
 */
74
public class MIRunControl extends AbstractDsfService implements IRunControl
62
public class MIRunControl extends AbstractDsfService implements IMIRunControl
75
{
63
{
76
    protected class MIExecutionDMC extends AbstractDMContext
64
    private AbstractMIControl fConnection;
77
        implements IMIExecutionDMContext
78
    {
79
        /**
80
         * Integer ID that is used to identify the thread in the GDB/MI protocol.
81
         */
82
        private final int fThreadId;
83
    
84
        /**
85
         * Constructor for the context.  It should not be called directly by clients.
86
         * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)}
87
         * to create instances of this context based on the thread ID.
88
         * <p/>
89
         * Classes extending {@link MIRunControl} may also extend this class to include
90
         * additional information in the context.
91
         * 
92
         * @param sessionId Session that this context belongs to.
93
         * @param containerDmc The container that this context belongs to.
94
         * @param threadId GDB/MI thread identifier.
95
         */
96
        protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) {
97
            super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
98
            fThreadId = threadId;
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
130
    /**
131
     * Base class for events generated by the MI Run Control service.  Most events
132
     * generated by the MI Run Control service are directly caused by some MI event.
133
     * Other services may need access to the extended MI data carried in the event.
134
     * 
135
     * @param <V> DMC that this event refers to
136
     * @param <T> MIInfo object that is the direct cause of this event
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
182
    @Immutable
183
    protected static class ContainerSuspendedEvent extends SuspendedEvent
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
198
    @Immutable
199
    protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
200
        implements IResumedDMEvent
201
    {
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
226
    @Immutable
227
    protected static class ContainerResumedEvent extends ResumedEvent
228
        implements IContainerResumedDMEvent
229
    {
230
        final IExecutionDMContext[] triggeringDmcs;
231
232
        ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
233
            super(containerDmc, miInfo);
234
            this.triggeringDmcs = triggeringDmc != null
235
                ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
236
        }
237
        
238
        public IExecutionDMContext[] getTriggeringContexts() {
239
            return triggeringDmcs;
240
        }
241
    }
242
    
243
    @Immutable
244
    protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
245
        implements IStartedDMEvent
246
    {
247
        StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
248
            super(executionDmc, miInfo);
249
        }
250
    }
251
    
252
    @Immutable
253
    protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
254
        implements IExitedDMEvent
255
    {
256
        ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
257
            super(executionDmc, miInfo);
258
        }
259
    }
260
    
261
    private AbstractMIControl   fConnection;
262
	private CommandCache fMICommandCache;
65
	private CommandCache fMICommandCache;
263
    
66
    
264
    // state flags
67
    // State flags
265
	private boolean fSuspended = true;
68
	private boolean fSuspended = true;
266
    private boolean fResumePending = false;
69
    private boolean fResumePending = false;
267
	private boolean fStepping = false;
70
	private boolean fStepping = false;
Lines 291-299 Link Here
291
        fMICommandCache = new CommandCache(getSession(), fConnection);
94
        fMICommandCache = new CommandCache(getSession(), fConnection);
292
        fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
95
        fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
293
        getSession().addServiceEventListener(this, null);
96
        getSession().addServiceEventListener(this, null);
294
        
295
        //register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, new Hashtable<String,String>());
296
        
297
        rm.done();
97
        rm.done();
298
    }
98
    }
299
99
(-)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/output/CLIInfoThreadsInfo.java (-7 / +7 lines)
Lines 28-47 Link Here
28
 */
28
 */
29
public class CLIInfoThreadsInfo extends MIInfo {
29
public class CLIInfoThreadsInfo extends MIInfo {
30
30
31
	protected List<ThreadInfo> info; 
31
	protected List<CLIThreadInfo> info; 
32
	
32
	
33
	public CLIInfoThreadsInfo(MIOutput out) {
33
	public CLIInfoThreadsInfo(MIOutput out) {
34
		super(out);
34
		super(out);
35
		parse();
35
		parse();
36
	}
36
	}
37
37
38
	public class ThreadInfo{
38
	public class CLIThreadInfo{
39
		String fName;
39
		String fName;
40
		String fGdbId;
40
		String fGdbId;
41
		String fPid;
41
		String fPid;
42
		boolean fIsCurrentThread = false;
42
		boolean fIsCurrentThread = false;
43
		
43
		
44
		public ThreadInfo(String tid, String pid, String name, boolean isCurrentThread)
44
		public CLIThreadInfo(String tid, String pid, String name, boolean isCurrentThread)
45
		{
45
		{
46
			this.fName = name;
46
			this.fName = name;
47
			this.fGdbId = tid;
47
			this.fGdbId = tid;
Lines 56-67 Link Here
56
		public boolean isCurrentThread(){return fIsCurrentThread; }
56
		public boolean isCurrentThread(){return fIsCurrentThread; }
57
	}
57
	}
58
	
58
	
59
	public List<ThreadInfo> getThreadInfo(){
59
	public List<CLIThreadInfo> getThreadInfo(){
60
		return info; 
60
		return info; 
61
	}
61
	}
62
62
63
	protected void parse() {
63
	protected void parse() {
64
		info = new ArrayList<ThreadInfo>();
64
		info = new ArrayList<CLIThreadInfo>();
65
		if (isDone()) {
65
		if (isDone()) {
66
			MIOutput out = getMIOutput();
66
			MIOutput out = getMIOutput();
67
			MIOOBRecord[] oobs = out.getMIOOBRecords();
67
			MIOOBRecord[] oobs = out.getMIOOBRecords();
Lines 76-82 Link Here
76
		}
76
		}
77
	}
77
	}
78
78
79
	protected void parseThreadInfo(String str, List<ThreadInfo> info) {
79
	protected void parseThreadInfo(String str, List<CLIThreadInfo> info) {
80
			// Fetch the OS ThreadId & Find the current thread 
80
			// Fetch the OS ThreadId & Find the current thread 
81
			if(str.length() > 0 ){
81
			if(str.length() > 0 ){
82
				Pattern pattern = Pattern.compile("(^\\*?\\s*\\d+)(\\s*Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)",  Pattern.MULTILINE); //$NON-NLS-1$
82
				Pattern pattern = Pattern.compile("(^\\*?\\s*\\d+)(\\s*Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)",  Pattern.MULTILINE); //$NON-NLS-1$
Lines 88-94 Link Here
88
						isCurrentThread = true;
88
						isCurrentThread = true;
89
						id = id.substring(1).trim();
89
						id = id.substring(1).trim();
90
					}
90
					}
91
					info.add(new ThreadInfo(id, matcher.group(5), "", isCurrentThread)); //$NON-NLS-1$
91
					info.add(new CLIThreadInfo(id, matcher.group(5), "", isCurrentThread)); //$NON-NLS-1$
92
				}
92
				}
93
			}
93
			}
94
	}
94
	}
(-)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 (+244 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.concurrent.Immutable;
15
import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
16
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
17
import org.eclipse.dd.dsf.datamodel.IDMContext;
18
import org.eclipse.dd.dsf.datamodel.IDMEvent;
19
import org.eclipse.dd.dsf.debug.service.IRunControl;
20
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
21
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
22
import org.eclipse.dd.mi.service.command.events.MIErrorEvent;
23
import org.eclipse.dd.mi.service.command.events.MIEvent;
24
import org.eclipse.dd.mi.service.command.events.MIRunningEvent;
25
import org.eclipse.dd.mi.service.command.events.MISharedLibEvent;
26
import org.eclipse.dd.mi.service.command.events.MISignalEvent;
27
import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
28
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
29
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
30
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
31
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
32
33
/**
34
 * This interface provides access to controlling and monitoring the execution 
35
 * state of a process being debugged.  This interface does not actually 
36
 * provide methods for creating or destroying execution contexts, it doesn't
37
 * even have methods for getting labels.  That's because it is expected that
38
 * higher level services, ones that deal with processes, kernels, or target 
39
 * features will provide that functionality. 
40
 */
41
public interface IMIRunControl extends IRunControl
42
{
43
	class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext
44
	{
45
		/**
46
		 * Integer ID that is used to identify the thread in the GDB/MI protocol.
47
		 */
48
		private final int fThreadId;
49
50
		/**
51
		 * Constructor for the context.  It should not be called directly by clients.
52
		 * Instead clients should call {@link MIRunControl#createMIExecutionContext(IContainerDMContext, int)}
53
		 * to create instances of this context based on the thread ID.
54
		 * <p/>
55
		 * Classes extending {@link MIRunControl} may also extend this class to include
56
		 * additional information in the context.
57
		 * 
58
		 * @param sessionId Session that this context belongs to.
59
		 * @param containerDmc The container that this context belongs to.
60
		 * @param threadId GDB/MI thread identifier.
61
		 */
62
		protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) {
63
			super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
64
			fThreadId = threadId;
65
		}
66
67
		/**
68
		 * Returns the GDB/MI thread identifier of this context.
69
		 * @return
70
		 */
71
		public int getThreadId(){
72
			return fThreadId;
73
		}
74
75
		@Override
76
		public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; }  //$NON-NLS-1$ //$NON-NLS-2$
77
78
		@Override
79
		public boolean equals(Object obj) {
80
			return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId == fThreadId;
81
		}
82
83
		@Override
84
		public int hashCode() { return super.baseHashCode() ^ fThreadId; }
85
	}
86
87
	@Immutable
88
	static class ExecutionData implements IExecutionDMData {
89
		private final StateChangeReason fReason;
90
		ExecutionData(StateChangeReason reason) {
91
			fReason = reason;
92
		}
93
		public StateChangeReason getStateChangeReason() { return fReason; }
94
	}
95
96
	/**
97
	 * Base class for events generated by the MI Run Control service.  Most events
98
	 * generated by the MI Run Control service are directly caused by some MI event.
99
	 * Other services may need access to the extended MI data carried in the event.
100
	 * 
101
	 * @param <V> DMC that this event refers to
102
	 * @param <T> MIInfo object that is the direct cause of this event
103
	 * @see MIRunControl
104
	 */
105
	@Immutable
106
	static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V>
107
	implements IDMEvent<V>, IMIDMEvent
108
	{
109
		final private T fMIInfo;
110
		public RunControlEvent(V dmc, T miInfo) {
111
			super(dmc);
112
			fMIInfo = miInfo;
113
		}
114
115
		public T getMIEvent() { return fMIInfo; }
116
	}
117
118
	/**
119
	 * Indicates that the given thread has been suspended.
120
	 */
121
	@Immutable
122
	static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
123
	implements ISuspendedDMEvent
124
	{
125
		SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
126
			super(ctx, miInfo);
127
		}
128
129
		public StateChangeReason getReason() {
130
			if (getMIEvent() instanceof MIBreakpointHitEvent) {
131
				return StateChangeReason.BREAKPOINT;
132
			} else if (getMIEvent() instanceof MISteppingRangeEvent) {
133
				return StateChangeReason.STEP;
134
			} else if (getMIEvent() instanceof MISharedLibEvent) {
135
				return StateChangeReason.SHAREDLIB;
136
			}else if (getMIEvent() instanceof MISignalEvent) {
137
				return StateChangeReason.SIGNAL;
138
			}else if (getMIEvent() instanceof MIWatchpointTriggerEvent) {
139
				return StateChangeReason.WATCHPOINT;
140
			}else if (getMIEvent() instanceof MIErrorEvent) {
141
				return StateChangeReason.ERROR;
142
			}else {
143
				return StateChangeReason.USER_REQUEST;
144
			}
145
		}
146
	}
147
148
	@Immutable
149
	static class ContainerSuspendedEvent extends SuspendedEvent
150
	implements IContainerSuspendedDMEvent
151
	{
152
		final IExecutionDMContext[] triggeringDmcs;
153
		ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
154
			super(containerDmc, miInfo);
155
			this.triggeringDmcs = triggeringDmc != null
156
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
157
		}
158
159
		public IExecutionDMContext[] getTriggeringContexts() {
160
			return triggeringDmcs;
161
		}
162
	}
163
164
	@Immutable
165
	static class ThreadSuspendedEvent extends SuspendedEvent
166
	{
167
		ThreadSuspendedEvent(IExecutionDMContext executionDmc, MIStoppedEvent miInfo) {
168
			super(executionDmc, miInfo);
169
		}
170
	}
171
172
	@Immutable
173
	static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
174
	implements IResumedDMEvent
175
	{
176
		ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
177
			super(ctx, miInfo);
178
		}
179
180
		public StateChangeReason getReason() {
181
			switch(getMIEvent().getType()) {
182
			case MIRunningEvent.CONTINUE:
183
				return StateChangeReason.USER_REQUEST;
184
			case MIRunningEvent.NEXT:
185
			case MIRunningEvent.NEXTI:
186
				return StateChangeReason.STEP;
187
			case MIRunningEvent.STEP:
188
			case MIRunningEvent.STEPI:
189
				return StateChangeReason.STEP;
190
			case MIRunningEvent.FINISH:
191
				return StateChangeReason.STEP;
192
			case MIRunningEvent.UNTIL:
193
			case MIRunningEvent.RETURN:
194
				break;
195
			}
196
			return StateChangeReason.UNKNOWN;
197
		}
198
	}
199
200
	@Immutable
201
	static class ContainerResumedEvent extends ResumedEvent
202
	implements IContainerResumedDMEvent
203
	{
204
		final IExecutionDMContext[] triggeringDmcs;
205
206
		ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
207
			super(containerDmc, miInfo);
208
			this.triggeringDmcs = triggeringDmc != null
209
			? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
210
		}
211
212
		public IExecutionDMContext[] getTriggeringContexts() {
213
			return triggeringDmcs;
214
		}
215
	}
216
217
	@Immutable
218
	static class ThreadResumedEvent extends ResumedEvent
219
	{
220
		ThreadResumedEvent(IExecutionDMContext executionDmc, MIRunningEvent miInfo) {
221
			super(executionDmc, miInfo);
222
		}
223
	}
224
225
	@Immutable
226
	static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
227
	implements IStartedDMEvent
228
	{
229
		StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
230
			super(executionDmc, miInfo);
231
		}
232
	}
233
234
	@Immutable
235
	static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
236
	implements IExitedDMEvent
237
	{
238
		ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
239
			super(executionDmc, miInfo);
240
		}
241
	}
242
243
	public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId);
244
}
(-)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/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/MIRunControlNS.java (+641 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
package org.eclipse.dd.mi.service;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
17
import org.eclipse.core.runtime.IStatus;
18
import org.eclipse.core.runtime.Status;
19
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
20
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
21
import org.eclipse.dd.dsf.datamodel.DMContexts;
22
import org.eclipse.dd.dsf.datamodel.IDMContext;
23
import org.eclipse.dd.dsf.datamodel.IDMEvent;
24
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
25
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
26
import org.eclipse.dd.dsf.service.AbstractDsfService;
27
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
28
import org.eclipse.dd.dsf.service.DsfSession;
29
import org.eclipse.dd.mi.internal.MIPlugin;
30
import org.eclipse.dd.mi.service.command.AbstractMIControl;
31
import org.eclipse.dd.mi.service.command.commands.MIExecContinue;
32
import org.eclipse.dd.mi.service.command.commands.MIExecFinish;
33
import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt;
34
import org.eclipse.dd.mi.service.command.commands.MIExecNext;
35
import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction;
36
import org.eclipse.dd.mi.service.command.commands.MIExecStep;
37
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
38
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
39
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
40
import org.eclipse.dd.mi.service.command.events.MIGDBExitEvent;
41
import org.eclipse.dd.mi.service.command.events.MIRunningEvent;
42
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
43
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
44
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
45
import org.eclipse.dd.mi.service.command.output.MIInfo;
46
import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo;
47
import org.osgi.framework.BundleContext;
48
49
/**
50
 * Implementation note: This class implements event handlers for the events that
51
 * are generated by this service itself. When the event is dispatched, these
52
 * handlers will be called first, before any of the clients. These handlers
53
 * update the service's internal state information to make them consistent with
54
 * the events being issued. Doing this in the handlers as opposed to when the
55
 * events are generated, guarantees that the state of the service will always be
56
 * consistent with the events. The purpose of this pattern is to allow clients
57
 * that listen to service events and track service state, to be perfectly in
58
 * sync with the service state.
59
 */
60
public class MIRunControlNS extends AbstractDsfService implements
61
		IMIRunControl {
62
63
	protected class MIThreadRunState {
64
		// State flags
65
		boolean fSuspended = false;
66
		boolean fResumePending = false;
67
		boolean fStepping = false;
68
		StateChangeReason fStateChangeReason;
69
	}
70
71
	///////////////////////////////////////////////////////////////////////////
72
	// MIRunControlNS
73
	///////////////////////////////////////////////////////////////////////////
74
75
	private AbstractMIControl fConnection;
76
	private CommandCache fMICommandCache;
77
78
	private boolean fTerminated = false;
79
80
	// ThreadStates indexed by the execution context
81
	protected Map<IMIExecutionDMContext, MIThreadRunState> fThreadRunStates = new HashMap<IMIExecutionDMContext, MIThreadRunState>();
82
83
	///////////////////////////////////////////////////////////////////////////
84
	// Initialization and shutdown
85
	///////////////////////////////////////////////////////////////////////////
86
87
	public MIRunControlNS(DsfSession session) {
88
		super(session);
89
	}
90
91
	@Override
92
	public void initialize(final RequestMonitor rm) {
93
		super.initialize(new RequestMonitor(getExecutor(), rm) {
94
			@Override
95
			protected void handleSuccess() {
96
				doInitialize(rm);
97
			}
98
		});
99
	}
100
101
	private void doInitialize(final RequestMonitor rm) {
102
		fConnection = getServicesTracker().getService(AbstractMIControl.class);
103
		fMICommandCache = new CommandCache(getSession(), fConnection);
104
		fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
105
		getSession().addServiceEventListener(this, null);
106
		rm.done();
107
	}
108
109
	@Override
110
	public void shutdown(final RequestMonitor rm) {
111
		getSession().removeServiceEventListener(this);
112
		fMICommandCache.reset();
113
		super.shutdown(rm);
114
	}
115
116
	///////////////////////////////////////////////////////////////////////////
117
	// AbstractDsfService
118
	///////////////////////////////////////////////////////////////////////////
119
120
	@Override
121
	protected BundleContext getBundleContext() {
122
		return MIPlugin.getBundleContext();
123
	}
124
125
	///////////////////////////////////////////////////////////////////////////
126
	// IDMService
127
	///////////////////////////////////////////////////////////////////////////
128
129
	@SuppressWarnings("unchecked")
130
	public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
131
		if (dmc instanceof IExecutionDMContext) {
132
			getExecutionData((IExecutionDMContext) dmc, (DataRequestMonitor<IExecutionDMData>) rm);
133
		} else {
134
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
135
			rm.done();
136
		}
137
	}
138
139
	///////////////////////////////////////////////////////////////////////////
140
	// IRunControl
141
	///////////////////////////////////////////////////////////////////////////
142
143
	// ------------------------------------------------------------------------
144
	// Suspend
145
	// ------------------------------------------------------------------------
146
147
	public boolean isSuspended(IExecutionDMContext context) {
148
149
		// Thread case
150
		if (context instanceof MIExecutionDMC) {
151
			MIThreadRunState threadState = fThreadRunStates.get(context);
152
			return (threadState == null) ? false : !fTerminated && threadState.fSuspended;
153
		}
154
155
		// Container case
156
		if (context instanceof IContainerDMContext) {
157
			boolean isSuspended = false;
158
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
159
				if (DMContexts.isAncestorOf(threadContext, context)) {
160
					isSuspended |= isSuspended(threadContext);
161
				}
162
			}
163
			return isSuspended;
164
		}
165
166
		// Default case
167
		return false;
168
	}
169
170
	public void canSuspend(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) {
171
172
		// Thread case
173
		if (context instanceof MIExecutionDMC) {
174
			rm.setData(doCanSuspend(context));
175
			rm.done();
176
			return;
177
		}
178
179
		// Container case
180
		if (context instanceof IContainerDMContext) {
181
			boolean canSuspend = false;
182
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
183
				if (DMContexts.isAncestorOf(threadContext, context)) {
184
					canSuspend |= doCanSuspend(threadContext);
185
				}
186
			}
187
			rm.setData(canSuspend);
188
			rm.done();
189
			return;
190
		}
191
192
		// Default case
193
		rm.setData(false);
194
		rm.done();
195
	}
196
197
	private boolean doCanSuspend(IExecutionDMContext context) {
198
		MIThreadRunState threadState = fThreadRunStates.get(context);
199
		return (threadState == null) ? false : !fTerminated && !threadState.fSuspended;
200
	}
201
202
	public void suspend(IExecutionDMContext context, final RequestMonitor rm) {
203
204
		assert context != null;
205
206
		// Thread case
207
		IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
208
		if (thread != null) {
209
			doSuspendThread(thread, rm);
210
			return;
211
		}
212
213
		// Container case
214
		IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class);
215
		if (container != null) {
216
			doSuspendContainer(container, rm);
217
			return;
218
		}
219
220
		// Default case
221
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
222
		rm.done();
223
	}
224
225
	private void doSuspendThread(IMIExecutionDMContext context, final RequestMonitor rm) {
226
227
		if (!doCanSuspend(context)) {
228
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
229
				"Given context: " + context + ", is already suspended.", null)); //$NON-NLS-1$ //$NON-NLS-2$
230
			rm.done();
231
			return;
232
		}
233
234
		MIExecInterrupt cmd = new MIExecInterrupt(context, true);
235
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
236
	}
237
238
	private void doSuspendContainer(IExecutionDMContext context, final RequestMonitor rm) {
239
		MIExecInterrupt cmd = new MIExecInterrupt(context, true);
240
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
241
	}
242
243
	// ------------------------------------------------------------------------
244
	// Resume
245
	// ------------------------------------------------------------------------
246
247
	public void canResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) {
248
249
		// Thread case
250
		if (context instanceof MIExecutionDMC) {
251
			rm.setData(doCanResume(context));
252
			rm.done();
253
			return;
254
		}
255
256
		// Container case
257
		if (context instanceof IContainerDMContext) {
258
			boolean canSuspend = false;
259
			for (IMIExecutionDMContext threadContext : fThreadRunStates.keySet()) {
260
				if (DMContexts.isAncestorOf(threadContext, context)) {
261
					canSuspend |= doCanResume(threadContext);
262
				}
263
			}
264
			rm.setData(canSuspend);
265
			rm.done();
266
			return;
267
		}
268
269
		// Default case
270
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
271
		rm.done();
272
	}
273
274
	private boolean doCanResume(IExecutionDMContext context) {
275
		MIThreadRunState threadState = fThreadRunStates.get(context);
276
		return (threadState == null) ? false : !fTerminated && threadState.fSuspended && !threadState.fResumePending;
277
	}
278
279
	public void resume(IExecutionDMContext context, final RequestMonitor rm) {
280
281
		assert context != null;
282
283
		// Thread case
284
		IMIExecutionDMContext thread = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
285
		if (thread != null) {
286
			doResumeThread(thread, rm);
287
			return;
288
		}
289
290
		// Container case
291
		IContainerDMContext container = DMContexts.getAncestorOfType(context, IContainerDMContext.class);
292
		if (container != null) {
293
			doResumeContainer(container, rm);
294
			return;
295
		}
296
297
		// Default case
298
		rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid context type.", null)); //$NON-NLS-1$
299
		rm.done();
300
	}
301
302
	private void doResumeThread(IMIExecutionDMContext context, final RequestMonitor rm) {
303
304
		if (!doCanResume(context)) {
305
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
306
				"Given context: " + context + ", is already running.", null)); //$NON-NLS-1$ //$NON-NLS-2$
307
			rm.done();
308
			return;
309
		}
310
311
		MIThreadRunState threadState = fThreadRunStates.get(context);
312
		if (threadState == null) {
313
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
314
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
315
			rm.done();
316
			return;
317
		}
318
		threadState.fResumePending = true;
319
320
		// Cygwin GDB will accept commands and execute them after the step
321
		// which is not what we want, so mark the target as unavailable
322
		// as soon as we send a resume command.
323
		fMICommandCache.setContextAvailable(context, false);
324
325
		MIExecContinue cmd = new MIExecContinue(context, true);
326
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
327
	}
328
329
	private void doResumeContainer(IExecutionDMContext context, final RequestMonitor rm) {
330
		MIExecContinue cmd = new MIExecContinue(context, true);
331
		fConnection.queueCommand(cmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
332
	}
333
334
	// ------------------------------------------------------------------------
335
	// Step
336
	// ------------------------------------------------------------------------
337
338
	public boolean isStepping(IExecutionDMContext context) {
339
340
		// If it's a thread, just look it up
341
		if (context instanceof MIExecutionDMC) {
342
			MIThreadRunState threadState = fThreadRunStates.get(context);
343
			return (threadState == null) ? false : !fTerminated && threadState.fStepping;
344
		}
345
346
		// Default case
347
		return false;
348
	}
349
350
	public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm) {
351
352
		// If it's a thread, just look it up
353
		if (context instanceof MIExecutionDMC) {
354
			canResume(context, rm);
355
			return;
356
		}
357
358
		// If it's a container, then we don't want to step it
359
		rm.setData(false);
360
		rm.done();
361
	}
362
363
	public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) {
364
365
		assert context != null;
366
367
		IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
368
		if (dmc == null) {
369
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
370
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
371
			rm.done();
372
			return;
373
		}
374
375
		if (!doCanResume(context)) {
376
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
377
				"Cannot resume context", null)); //$NON-NLS-1$
378
			rm.done();
379
			return;
380
		}
381
382
		MIThreadRunState threadState = fThreadRunStates.get(context);
383
		if (threadState == null) {
384
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
385
				"Given context: " + context + " can't be found.", null)); //$NON-NLS-1$ //$NON-NLS-2$
386
			rm.done();
387
			return;
388
		}
389
390
		threadState.fResumePending = true;
391
		threadState.fStepping = true;
392
393
		// Cygwin GDB will accept commands and execute them after the step
394
		// which is not what we want, so mark the target as unavailable
395
		// as soon as we send a resume command.
396
		fMICommandCache.setContextAvailable(context, false);
397
398
		switch (stepType) {
399
		case STEP_INTO:
400
			fConnection.queueCommand(new MIExecStep(dmc, true),
401
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
402
			break;
403
		case STEP_OVER:
404
			fConnection.queueCommand(new MIExecNext(dmc, true),
405
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
406
			break;
407
		case STEP_RETURN:
408
			// The -exec-finish command operates on the selected stack frame, but here we always
409
			// want it to operate on the stop stack frame. So we manually create a top-frame
410
			// context to use with the MI command.
411
			// We get a local instance of the stack service because the stack service can be shut
412
			// down before the run control service is shut down. So it is possible for the
413
			// getService() request below to return null.
414
			MIStack stackService = getServicesTracker().getService(MIStack.class);
415
			if (stackService != null) {
416
				IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0);
417
				fConnection.queueCommand(new MIExecFinish(topFrameDmc),
418
						new DataRequestMonitor<MIInfo>(getExecutor(), rm));
419
			} else {
420
				rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
421
						"Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$
422
				rm.done();
423
			}
424
			break;
425
		case INSTRUCTION_STEP_INTO:
426
			fConnection.queueCommand(new MIExecStepInstruction(dmc, true),
427
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
428
			break;
429
		case INSTRUCTION_STEP_OVER:
430
			fConnection.queueCommand(new MIExecNextInstruction(dmc, true),
431
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
432
			break;
433
		default:
434
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,
435
					INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$
436
			rm.done();
437
		}
438
	}
439
440
	// ------------------------------------------------------------------------
441
	// Run to line
442
	// ------------------------------------------------------------------------
443
444
	// Later add support for Address and function.
445
	// skipBreakpoints is not used at the moment. Implement later
446
	public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm) {
447
448
		assert context != null;
449
450
		IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
451
		if (dmc == null) {
452
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
453
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
454
			rm.done();
455
			return;
456
		}
457
458
		if (!doCanResume(context)) {
459
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
460
				"Cannot resume context", null)); //$NON-NLS-1$
461
			rm.done();
462
			return;
463
		}
464
465
		MIThreadRunState threadState = fThreadRunStates.get(context);
466
		if (threadState == null) {
467
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_STATE,
468
				"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
469
			rm.done();
470
			return;
471
		}
472
473
		threadState.fResumePending = true;
474
		fMICommandCache.setContextAvailable(context, false);
475
		fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$
476
				new DataRequestMonitor<MIInfo>(getExecutor(), rm));
477
	}
478
479
	// ------------------------------------------------------------------------
480
	// Support functions
481
	// ------------------------------------------------------------------------
482
483
	public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
484
		fMICommandCache.execute(new MIThreadListIds(containerDmc),
485
				new DataRequestMonitor<MIThreadListIdsInfo>(getExecutor(), rm) {
486
					@Override
487
					protected void handleSuccess() {
488
						rm.setData(makeExecutionDMCs(containerDmc, getData()));
489
						rm.done();
490
					}
491
				});
492
	}
493
494
	private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerCtx, MIThreadListIdsInfo info) {
495
		IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length];
496
		for (int i = 0; i < info.getThreadIds().length; i++) {
497
			executionDmcs[i] = createMIExecutionContext(containerCtx, info.getThreadIds()[i]);
498
		}
499
		return executionDmcs;
500
	}
501
502
	public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) {
503
		MIThreadRunState threadState = fThreadRunStates.get(dmc);
504
		if (threadState == null) {
505
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,INVALID_HANDLE,
506
				"Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
507
			rm.done();
508
			return;
509
		}
510
511
		if (dmc instanceof IMIExecutionDMContext) {
512
			rm.setData(new ExecutionData(threadState.fSuspended ? threadState.fStateChangeReason : null));
513
		} else {
514
			rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE,
515
				"Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
516
		}
517
		rm.done();
518
	}
519
520
	///////////////////////////////////////////////////////////////////////////
521
	// IMIRunControl
522
	///////////////////////////////////////////////////////////////////////////
523
524
	public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) {
525
		return new MIExecutionDMC(getSession().getId(), container, threadId);
526
	}
527
528
	///////////////////////////////////////////////////////////////////////////
529
	// IMIRunControl
530
	///////////////////////////////////////////////////////////////////////////
531
532
	public CommandCache getCache() {
533
		return fMICommandCache;
534
	}
535
536
	///////////////////////////////////////////////////////////////////////////
537
	// Event handlers
538
	///////////////////////////////////////////////////////////////////////////
539
540
	@DsfServiceEventHandler
541
	public void eventDispatched(final MIRunningEvent e) {
542
		IDMEvent<?> event = null;
543
		// Find the container context, which is used in multi-threaded debugging.
544
		IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
545
		event = (executionDmc != null) ? new ThreadResumedEvent(e.getDMContext(), e) : new ResumedEvent(e.getDMContext(), e);
546
		getSession().dispatchEvent(event, getProperties());
547
	}
548
549
	@DsfServiceEventHandler
550
	public void eventDispatched(final MIStoppedEvent e) {
551
		IDMEvent<?> event = null;
552
		// Find the container context, which is used in multi-threaded debugging.
553
		IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
554
		event = (executionDmc != null) ? new ThreadSuspendedEvent(e.getDMContext(), e) : new SuspendedEvent(e.getDMContext(), e);
555
		getSession().dispatchEvent(event, getProperties());
556
	}
557
558
	@DsfServiceEventHandler
559
	public void eventDispatched(final MIThreadCreatedEvent e) {
560
		IContainerDMContext containerDmc = e.getDMContext();
561
		IMIExecutionDMContext executionCtx = null;
562
		if (e.getId() != -1) {
563
			executionCtx = createMIExecutionContext(containerDmc, e.getId());
564
			if (fThreadRunStates.get(executionCtx) == null) {
565
				fThreadRunStates.put(executionCtx, new MIThreadRunState());
566
			}
567
		}
568
		getSession().dispatchEvent(new StartedDMEvent(executionCtx, e),	getProperties());
569
		fMICommandCache.reset();
570
	}
571
572
	@DsfServiceEventHandler
573
	public void eventDispatched(final MIThreadExitEvent e) {
574
		IContainerDMContext containerDmc = e.getDMContext();
575
		IMIExecutionDMContext executionCtx = null;
576
		if (e.getId() != -1) {
577
			executionCtx = createMIExecutionContext(containerDmc, e.getId());
578
			fThreadRunStates.remove(executionCtx);
579
		}
580
		getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties());
581
		fMICommandCache.reset();
582
	}
583
584
	@DsfServiceEventHandler
585
	public void eventDispatched(ThreadResumedEvent e) {
586
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
587
		if (context == null) {
588
			return;
589
		}
590
		StateChangeReason reason = e.getReason();
591
		boolean isStepping = reason.equals(StateChangeReason.STEP);
592
		MIThreadRunState threadState = fThreadRunStates.get(context);
593
		if (threadState == null) {
594
			threadState = new MIThreadRunState();
595
			fThreadRunStates.put(context, threadState);
596
		}
597
		threadState.fSuspended = false;
598
		threadState.fResumePending = false;
599
		threadState.fStateChangeReason = reason;
600
		threadState.fStepping = isStepping;
601
		fMICommandCache.setContextAvailable(context, false);
602
603
		// This is a hack: CommandCache.setContextAvailable(context, false) effectively
604
		// removes the context and all its ancestors from the "available contexts list". 
605
		// However, in non-stop mode, it is OK to issue commands at any time to the
606
		// parent container (e.g. suspend). Therefore, we force it to be available.
607
		fMICommandCache.setContextAvailable(context.getParents()[0], true);
608
609
		if (!isStepping) {
610
			fMICommandCache.reset();
611
		}
612
	}
613
614
	@DsfServiceEventHandler
615
	public void eventDispatched(ThreadSuspendedEvent e) {
616
		IMIExecutionDMContext context = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
617
		if (context == null) {
618
			return;
619
		}
620
		StateChangeReason reason = e.getReason();
621
		fMICommandCache.setContextAvailable(context, true);
622
		fMICommandCache.setContextAvailable(context.getParents()[0], true);
623
		fMICommandCache.reset();
624
625
		MIThreadRunState threadState = fThreadRunStates.get(context);
626
		if (threadState == null) {
627
			threadState = new MIThreadRunState();
628
			fThreadRunStates.put(context, threadState);
629
		}
630
		threadState.fSuspended = true;
631
		threadState.fResumePending = false;
632
		threadState.fStepping = false;
633
		threadState.fStateChangeReason = reason;
634
	}
635
636
	@DsfServiceEventHandler
637
	public void eventDispatched(MIGDBExitEvent e) {
638
		fTerminated = true;
639
	}
640
641
}
(-)src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ThreadVMNode.java (-4 / +4 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.GDBThreadData;
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;
(-)src/org/eclipse/dd/gdb/internal/ui/viewmodel/launch/ContainerVMNode.java (-5 / +5 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.GDBProcessData;
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 151-157 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,
Lines 203-209 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,
(-)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 (-4 / +4 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.GDBThreadData;
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-502 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<GDBThreadData>(
502
                        ImmediateExecutor.getInstance(), rm) {
502
                        ImmediateExecutor.getInstance(), rm) {
(-)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

Return to bug 237556