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 237306 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/cdt/debug/core/CDebugUtils.java (+23 lines)
Lines 20-25 Link Here
20
import java.util.Arrays;
20
import java.util.Arrays;
21
import java.util.Iterator;
21
import java.util.Iterator;
22
import java.util.List;
22
import java.util.List;
23
import java.util.Map;
23
24
24
import javax.xml.transform.OutputKeys;
25
import javax.xml.transform.OutputKeys;
25
import javax.xml.transform.Transformer;
26
import javax.xml.transform.Transformer;
Lines 688-691 Link Here
688
	private static void throwCoreException(String msg, Exception innerException, int code) throws CoreException {
689
	private static void throwCoreException(String msg, Exception innerException, int code) throws CoreException {
689
		throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), code, msg, innerException));
690
		throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), code, msg, innerException));
690
	}
691
	}
692
	
693
	/**
694
	 * Generic method to fetch an attribute from a Map that has keys of type String.  The defaultValue
695
	 * parameter will be returned if the map does not contain the key, or if the matching value is not
696
	 * of the correct type.
697
	 * 
698
	 * @param <V> The type of the value we are looking for.  Specified by the type of defaultValue.
699
	 * @param attributes The map with keys of type String, and values of any type.  Can not be null.
700
	 * @param key They key for which we want the value.
701
	 * @param defaultValue The default value to return if the key is not found in the map, or if the value found
702
	 *                     is not of the same type as defaultValue. Can not be null.
703
	 * @return The value, if found and of the same type as defaultValue.  Else, returns defaultValue.
704
	 * @since 7.1
705
	 */
706
	@SuppressWarnings("unchecked")
707
	public static <V> V getAttribute(Map<String, ?> attributes, String key, V defaultValue) {
708
		Object value = attributes.get(key);
709
		if (defaultValue.getClass().isInstance(value)) {
710
			return (V)value;
711
		}
712
		return defaultValue;
713
	}
691
}
714
}
(-)src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java (-2 / +11 lines)
Lines 26-31 Link Here
26
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
26
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
27
import org.eclipse.cdt.dsf.datamodel.IDMContext;
27
import org.eclipse.cdt.dsf.datamodel.IDMContext;
28
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
28
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
29
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
29
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
30
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
30
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
31
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
31
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
32
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
Lines 37-42 Link Here
37
import org.eclipse.cdt.dsf.gdb.service.SessionType;
38
import org.eclipse.cdt.dsf.gdb.service.SessionType;
38
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
39
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
39
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
40
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
41
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
40
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
42
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
41
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
43
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
42
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
44
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
Lines 64-70 Link Here
64
	private CommandFactory fCommandFactory;
66
	private CommandFactory fCommandFactory;
65
67
66
	private DsfServicesTracker fTracker;
68
	private DsfServicesTracker fTracker;
67
69
	private IMIContainerDMContext fInitialContainerCtx;
70
	
68
	public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, IProgressMonitor pm) {
71
	public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, IProgressMonitor pm) {
69
		super(executor, pm, LaunchMessages.getString("FinalLaunchSequence.0"), LaunchMessages.getString("FinalLaunchSequence.1"));     //$NON-NLS-1$ //$NON-NLS-2$
72
		super(executor, pm, LaunchMessages.getString("FinalLaunchSequence.0"), LaunchMessages.getString("FinalLaunchSequence.1"));     //$NON-NLS-1$ //$NON-NLS-2$
70
		fLaunch = launch;
73
		fLaunch = launch;
Lines 131-136 Link Here
131
			return;
134
			return;
132
		}
135
		}
133
136
137
        // We can cheat a little.  Since we know GDB starts off focused on the one
138
		// groupId it automatically created, we can simply create a container with the 'null'
139
		// groupId, which will get ignored and will use the process currently in focus.
140
		IProcessDMContext procCtx = fProcService.createProcessContext(fCommandControl.getContext(), null);
141
		fInitialContainerCtx = fProcService.createContainerContext(procCtx, null);
142
		
134
		requestMonitor.done();
143
		requestMonitor.done();
135
	}
144
	}
136
145
Lines 285-291 Link Here
285
		final IPath execPath = fGDBBackend.getProgramPath();
294
		final IPath execPath = fGDBBackend.getProgramPath();
286
		if (!noFileCommand && execPath != null && !execPath.isEmpty()) {
295
		if (!noFileCommand && execPath != null && !execPath.isEmpty()) {
287
			fCommandControl.queueCommand(
296
			fCommandControl.queueCommand(
288
					fCommandFactory.createMIFileExecAndSymbols(fCommandControl.getContext(), 
297
					fCommandFactory.createMIFileExecAndSymbols(fInitialContainerCtx, 
289
							execPath.toPortableString()), 
298
							execPath.toPortableString()), 
290
							new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor));
299
							new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor));
291
		} else {
300
		} else {
(-)src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java (-2 / +4 lines)
Lines 689-695 Link Here
689
    	rm.done();
689
    	rm.done();
690
    }
690
    }
691
    
691
    
692
    private boolean doIsDebuggerAttachSupported() {
692
    /** @since 4.0 */
693
    protected boolean doIsDebuggerAttachSupported() {
693
    	IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
694
    	IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
694
    	if (backend != null) {
695
    	if (backend != null) {
695
    		return backend.getIsAttachSession();
696
    		return backend.getIsAttachSession();
Lines 728-734 Link Here
728
	    }
729
	    }
729
	}
730
	}
730
731
731
    private boolean doCanDetachDebuggerFromProcess() {
732
    /** @since 4.0 */
733
    protected boolean doCanDetachDebuggerFromProcess() {
732
    	IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
734
    	IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
733
    	if (backend != null) {
735
    	if (backend != null) {
734
    		return backend.getIsAttachSession() && fCommandControl.isConnected();
736
    		return backend.getIsAttachSession() && fCommandControl.isConnected();
(-)src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java (+529 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.cdt.dsf.gdb.service;
12
13
import java.util.Map;
14
import java.util.Properties;
15
16
import org.eclipse.cdt.debug.core.CDebugUtils;
17
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
18
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
19
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
20
import org.eclipse.cdt.dsf.concurrent.ReflectionSequence;
21
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
22
import org.eclipse.cdt.dsf.concurrent.Sequence;
23
import org.eclipse.cdt.dsf.datamodel.DMContexts;
24
import org.eclipse.cdt.dsf.datamodel.IDMContext;
25
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
26
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
27
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
28
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
29
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
30
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
31
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
32
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
33
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
34
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
35
import org.eclipse.cdt.dsf.mi.service.command.output.MIAddInferiorInfo;
36
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
37
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
38
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
39
import org.eclipse.cdt.dsf.service.DsfSession;
40
import org.eclipse.core.runtime.CoreException;
41
import org.eclipse.core.runtime.IStatus;
42
import org.eclipse.core.runtime.Status;
43
44
/**
45
 * @since 4.0
46
 */
47
public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
48
    
49
    private CommandFactory fCommandFactory;
50
    private IGDBControl fCommandControl;
51
    private IGDBBackend fBackend;
52
    
53
	public GDBProcesses_7_2(DsfSession session) {
54
		super(session);
55
	}
56
57
	@Override
58
	public void initialize(final RequestMonitor requestMonitor) {
59
		super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
60
			@Override
61
			protected void handleSuccess() {
62
				doInitialize(requestMonitor);
63
			}
64
		});
65
	}
66
67
	/**
68
	 * This method initializes this service after our superclass's initialize()
69
	 * method succeeds.
70
	 * 
71
	 * @param requestMonitor
72
	 *            The call-back object to notify when this service's
73
	 *            initialization is done.
74
	 */
75
	private void doInitialize(RequestMonitor requestMonitor) {
76
		fCommandControl = getServicesTracker().getService(IGDBControl.class);
77
        fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
78
    	fBackend = getServicesTracker().getService(IGDBBackend.class);
79
80
    	requestMonitor.done();
81
	}
82
83
	@Override
84
	public void shutdown(RequestMonitor requestMonitor) {
85
		super.shutdown(requestMonitor);
86
	}
87
88
	@Override
89
	protected boolean doIsDebuggerAttachSupported() {
90
		return true;
91
	}
92
93
	@Override
94
	protected boolean doCanDetachDebuggerFromProcess() {
95
		return true;
96
	}
97
	
98
	protected class DebugNewProcessSequence extends ReflectionSequence {
99
100
		private String fBinaryName;
101
		private Map<String, Object> fAttributes;
102
		private IMIContainerDMContext fContainerCtx;
103
		// Store the dataRM so that we can fill it with the container context that we will be creating
104
		private DataRequestMonitor<IDMContext> fDataRequestMonitor;
105
		
106
		public DebugNewProcessSequence(IDMContext dmc, String file, Map<String, Object> attributes, final DataRequestMonitor<IDMContext> rm) {
107
			super(GDBProcesses_7_2.this.getExecutor(), rm);
108
			fBinaryName = file;
109
			fAttributes = attributes;
110
			fDataRequestMonitor = rm;
111
		}
112
113
		@Override
114
		protected String[] getExecutionOrder(String group) {
115
			if (GROUP_TOP_LEVEL.equals(group)) {
116
				return new String[] {
117
						"stepAddInferior",  //$NON-NLS-1$
118
						"stepSetEnvironmentVariables",   //$NON-NLS-1$
119
						"stepSetExecutable",   //$NON-NLS-1$
120
						"stepSetArguments",   //$NON-NLS-1$
121
						"stepStartExecution",   //$NON-NLS-1$
122
				};
123
			}
124
			return null;
125
		}
126
		
127
		/**
128
		 * Start executing the program.
129
		 */
130
		@Execute
131
		public void stepAddInferior(final RequestMonitor rm) {
132
	        fCommandControl.queueCommand(
133
	        		fCommandFactory.createMIAddInferior(fCommandControl.getContext()),
134
	        		new DataRequestMonitor<MIAddInferiorInfo>(ImmediateExecutor.getInstance(), rm) {
135
	        			@Override
136
	        			protected void handleSuccess() {
137
	        				final String groupId = getData().getGroupId();
138
	        				if (groupId == null || groupId.trim().length() == 0) {
139
	 				           rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid gdb group id.", null)); //$NON-NLS-1$
140
					           rm.done();
141
					           return;
142
	    					}
143
144
	        				IProcessDMContext procCtx = createProcessContext(fCommandControl.getContext(), null);
145
	        				fContainerCtx = createContainerContext(procCtx, groupId);
146
	        				rm.done();
147
	        			}
148
	        		});
149
		}
150
		
151
		/**
152
		 * Specify environment variables if needed
153
		 */
154
		@Execute
155
		public void stepSetEnvironmentVariables(RequestMonitor rm) {
156
			boolean clear = false;
157
			Properties properties = new Properties();
158
			try {
159
				// here we need to pass the proper container context
160
				clear = fBackend.getClearEnvironment();
161
				properties = fBackend.getEnvironmentVariables();
162
			} catch (CoreException e) {
163
				rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get environment information", e)); //$NON-NLS-1$
164
				rm.done();
165
				return;
166
			}
167
168
			if (clear == true || properties.size() > 0) {
169
				// here we need to pass the proper container context
170
				fCommandControl.setEnvironment(properties, clear, rm);
171
			} else {
172
				rm.done();
173
			}
174
		}
175
176
		/**
177
		 * Specify the executable file to be debugged and read the symbol table.
178
		 */
179
		@Execute
180
		public void stepSetExecutable(RequestMonitor rm) {
181
			boolean noFileCommand = CDebugUtils.getAttribute(fAttributes, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP,
182
											             	              IGDBLaunchConfigurationConstants.DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP_DEFAULT);
183
184
			if (!noFileCommand && fBinaryName != null && fBinaryName.length() > 0) {
185
				fCommandControl.queueCommand(
186
						fCommandFactory.createMIFileExecAndSymbols(fContainerCtx, fBinaryName), 
187
						new DataRequestMonitor<MIInfo>(getExecutor(), rm));
188
			} else {
189
				rm.done();
190
			}
191
		}
192
193
		/**
194
		 * Specify the arguments to the executable file.
195
		 */
196
		@Execute
197
		public void stepSetArguments(RequestMonitor rm) {
198
			try {
199
				String args = fBackend.getProgramArguments();
200
201
				if (args != null) {
202
					fCommandControl.queueCommand(
203
							// here we need to pass the proper container context
204
							fCommandFactory.createMIGDBSetArgs(fCommandControl.getContext(), args), 
205
							new DataRequestMonitor<MIInfo>(getExecutor(), rm));
206
				} else {
207
					rm.done();
208
				}
209
			} catch (CoreException e) {
210
				rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$
211
				rm.done();
212
			}    		
213
		}
214
215
		/**
216
		 * Start executing the program.
217
		 */
218
		@Execute
219
		public void stepStartExecution(final RequestMonitor rm) {
220
			startOrRestart(fContainerCtx, fAttributes, false, new DataRequestMonitor<IMIContainerDMContext>(ImmediateExecutor.getInstance(), rm) {
221
				@Override
222
				protected void handleSuccess() {
223
					// Set the container that we created
224
					fDataRequestMonitor.setData(getData());
225
					
226
					// Don't call fDataRequestMonitor.done(), the sequence will
227
					// automatically do that when we call rm.done();
228
					rm.done();
229
				}
230
			});
231
		}
232
	}
233
234
	@Override
235
	public void debugNewProcess(IDMContext dmc, String file, 
236
			                    Map<String, Object> attributes, DataRequestMonitor<IDMContext> rm) {
237
		Sequence debugNewProcess = new DebugNewProcessSequence(dmc, file, attributes, rm);
238
   		ImmediateExecutor.getInstance().execute(debugNewProcess);
239
	}
240
	
241
	@Override
242
    public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
243
		if (procCtx instanceof IMIProcessDMContext) {
244
	    	if (!doIsDebuggerAttachSupported()) {
245
	            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$
246
	            rm.done();    		
247
	    		return;
248
	    	}
249
	    	
250
	    	ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
251
	        fCommandControl.queueCommand(
252
	        		fCommandFactory.createMIAddInferior(controlDmc),
253
	        		new DataRequestMonitor<MIAddInferiorInfo>(getExecutor(), rm) {
254
	        			@Override
255
	        			protected void handleSuccess() {
256
	        				final String groupId = getData().getGroupId();
257
	        				if (groupId == null || groupId.trim().length() == 0) {
258
     				           rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid gdb group id.", null)); //$NON-NLS-1$
259
    				           rm.done();
260
    				           return;
261
        					}
262
	        				
263
	        				final IMIContainerDMContext containerDmc = createContainerContext(procCtx, groupId);
264
	        				fCommandControl.queueCommand(
265
	        						fCommandFactory.createMITargetAttach(containerDmc, ((IMIProcessDMContext)procCtx).getProcId()),
266
	        						new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
267
	        							@Override
268
	        							protected void handleSuccess() {
269
	        								rm.setData(containerDmc);
270
	        								rm.done();
271
	        							}
272
	        						});
273
	        			}
274
	        		});
275
	    } else {
276
            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
277
            rm.done();
278
	    }
279
	}
280
	
281
	@Override
282
    public void detachDebuggerFromProcess(IDMContext dmc, final RequestMonitor rm) {
283
    	
284
		final IMIContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
285
286
    	if (containerDmc != null) {
287
        	if (!doCanDetachDebuggerFromProcess()) {
288
                rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Detach not supported.", null)); //$NON-NLS-1$
289
                rm.done();
290
                return;
291
        	}
292
293
        	fCommandControl.queueCommand(
294
        			fCommandFactory.createMITargetDetach(containerDmc),
295
    				new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
296
    					@Override
297
    					protected void handleSuccess() {
298
    			        	fCommandControl.queueCommand(
299
    			        			fCommandFactory.createMIRemoveInferior(fCommandControl.getContext(), containerDmc.getGroupId()),
300
    			    				new DataRequestMonitor<MIInfo>(getExecutor(), rm));
301
    					}
302
    				});
303
    	} else {
304
            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
305
            rm.done();
306
	    }
307
	}
308
309
	protected class StartOrRestartProcessSequence extends ReflectionSequence {
310
		
311
		// This variable will be used to store the original container context,
312
		// but once the new process is start (restarted), it will contain the new
313
		// container context.  This new container context has for parent the process
314
		// context, which holds the new pid.
315
		private IMIContainerDMContext fContainerDmc;
316
		
317
    	private MIBreakpoint fUserBreakpoint = null;
318
    	private boolean fUserBreakpointIsOnMain = false;
319
    	private boolean fReverseEnabled;
320
    	private boolean fRestart;
321
    	private Map<String, Object> fAttributes;
322
		// Store the dataRM so that we can fill it with the container context that we will be creating
323
		private DataRequestMonitor<IMIContainerDMContext> fDataRequestMonitor;
324
325
		public StartOrRestartProcessSequence(IMIContainerDMContext containerDmc, Map<String, Object> attributes, 
326
											 boolean restart, DataRequestMonitor<IMIContainerDMContext> rm) {
327
			super(GDBProcesses_7_2.this.getExecutor(), rm);
328
			fContainerDmc = containerDmc;
329
			fAttributes = attributes;
330
			fRestart = restart;
331
			fDataRequestMonitor = rm;
332
			fReverseEnabled = CDebugUtils.getAttribute(attributes, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
333
													   IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
334
		}
335
336
		@Override
337
		protected String[] getExecutionOrder(String group) {
338
			if (GROUP_TOP_LEVEL.equals(group)) {
339
				return new String[] {
340
						"stepInsertStopOnMainBreakpoint",  //$NON-NLS-1$
341
						"stepSetBreakpointForReverse",   //$NON-NLS-1$
342
						"stepRunProgram",   //$NON-NLS-1$
343
						"stepSetReverseOff",   //$NON-NLS-1$
344
						"stepEnableReverse",   //$NON-NLS-1$
345
						"stepContinue",   //$NON-NLS-1$
346
				};
347
			}
348
			return null;
349
		}
350
		
351
		/**
352
		 * If the user requested a 'stopOnMain', let's set the temporary breakpoint
353
		 * where the user specified.
354
		 */
355
		@Execute
356
		public void stepInsertStopOnMainBreakpoint(final RequestMonitor rm) {
357
			boolean userRequestedStop = CDebugUtils.getAttribute(fAttributes, 
358
					ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN,
359
					false);
360
361
			if (userRequestedStop) {
362
				String userStopSymbol = CDebugUtils.getAttribute(fAttributes, 
363
						ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
364
						ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT);
365
366
				fCommandControl.queueCommand(
367
						fCommandFactory.createMIBreakInsert((IBreakpointsTargetDMContext)fCommandControl.getContext(),
368
								true, false, null, 0, userStopSymbol, 0),
369
								new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
370
							@Override
371
							public void handleSuccess() {
372
								if (getData() != null) {
373
									MIBreakpoint[] breakpoints = getData().getMIBreakpoints();
374
									if (breakpoints.length > 0) {
375
										fUserBreakpoint = breakpoints[0];
376
									}
377
								}
378
								rm.done();
379
							}
380
						});
381
			} else {
382
				rm.done();
383
			}
384
		}
385
386
		/*
387
		 * If reverse debugging, set a breakpoint on main to be able to enable reverse
388
		 * as early as possible.
389
		 * If the user has requested a stop at the same point, we could skip this breakpoint
390
		 * however, we have to first set it to find out!  So, we just leave it.
391
		 */
392
		@Execute
393
		public void stepSetBreakpointForReverse(final RequestMonitor rm) {
394
			if (fReverseEnabled) {
395
				fCommandControl.queueCommand(
396
						fCommandFactory.createMIBreakInsert((IBreakpointsTargetDMContext)fCommandControl.getContext(),
397
								true, false, null, 0, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT, 0),
398
								new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
399
							@Override
400
							public void handleSuccess() {
401
								if (getData() != null) {
402
									MIBreakpoint[] breakpoints = getData().getMIBreakpoints();
403
									if (breakpoints.length > 0 && fUserBreakpoint != null) {
404
										fUserBreakpointIsOnMain = breakpoints[0].getAddress().equals(fUserBreakpoint.getAddress());
405
									}
406
								}
407
								rm.done();
408
							}
409
						});
410
			} else {
411
				rm.done();
412
			}
413
		}
414
		/*
415
		 * Now, run the program.  Use either -exec-run or -exec-continue depending
416
		 * on whether we have remote session or not.
417
		 */
418
		@Execute
419
		public void stepRunProgram(final RequestMonitor rm) {
420
			ICommand<MIInfo> command;
421
			if (useContinueCommand(fAttributes, fRestart)) {
422
				command = fCommandFactory.createMIExecContinue(fContainerDmc);
423
			} else {
424
				command = fCommandFactory.createMIExecRun(fContainerDmc);	
425
			}
426
			fCommandControl.queueCommand(command, new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
427
				@Override
428
				protected void handleSuccess() {
429
					// Now that the process is started, the pid has been allocated
430
					// so we need to fetch the proper container context
431
					// We replace our current context which does not have the pid, with one that has the pid.
432
					fContainerDmc = createContainerContextFromGroupId(fCommandControl.getContext(), fContainerDmc.getGroupId());
433
					fDataRequestMonitor.setData(fContainerDmc);
434
					rm.done();
435
				}
436
			});
437
438
		}
439
		/*
440
		 * In case of a restart, reverse debugging should be marked as off here because
441
		 * GDB will have turned it off. We may turn it back on after.
442
		 */
443
		@Execute
444
		public void stepSetReverseOff(RequestMonitor rm) {
445
			// Although it only makes sense for a restart, it doesn't hurt
446
			// do to it all the time.
447
			GDBRunControl_7_0 reverseService = getServicesTracker().getService(GDBRunControl_7_0.class);
448
			if (reverseService != null) {
449
				reverseService.setReverseModeEnabled(false);
450
			}
451
			rm.done();
452
		}
453
		/*
454
		 * Since we have started the program, we can turn on reverse debugging if needed
455
		 */
456
		@Execute
457
		public void stepEnableReverse(RequestMonitor rm) {
458
			if (fReverseEnabled) {
459
				IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class);
460
				if (reverseService != null) {
461
					reverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
462
					return;
463
				}
464
			}
465
			rm.done();
466
		}
467
		/*
468
		 * Finally, if we are enabling reverse, and the userSymbolStop is not on main,
469
		 * we should do a continue because we are currently stopped on main but that 
470
		 * is not what the user requested
471
		 */
472
		@Execute
473
		public void stepContinue(RequestMonitor rm) {
474
			if (fReverseEnabled && !fUserBreakpointIsOnMain) {
475
				fCommandControl.queueCommand(fCommandFactory.createMIExecContinue(fContainerDmc),
476
						new DataRequestMonitor<MIInfo>(getExecutor(), rm));
477
			} else {
478
				rm.done();
479
			}
480
		}
481
	};
482
483
	/**
484
     * Insert breakpoint at entry if set, and start or restart the program.
485
     * Note that restart does not apply to remote or attach sessions.
486
     * 
487
     * If we want to enable Reverse debugging from the start of the program we do the following:
488
     * attachSession => enable reverse
489
     * else => set temp bp on main, run, enable reverse, continue if bp on main was not requested by user 
490
     */
491
    protected void startOrRestart(IMIContainerDMContext containerDmc, Map<String, Object> attributes, boolean restart, DataRequestMonitor<IMIContainerDMContext> rm) {
492
		final boolean reverseEnabled = CDebugUtils.getAttribute(attributes, IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
493
       																        IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
494
495
   		if (fBackend.getIsAttachSession()) {
496
   			// Restart does not apply to attach sessions.
497
   			//
498
   			// When attaching to a running process, we do not need to set a breakpoint or
499
   			// start the program; it is left up to the user.
500
   			// We only need to turn on Reverse Debugging if requested.
501
   			if (reverseEnabled) {
502
   				IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class);
503
   				if (reverseService != null) {
504
   					reverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
505
   					return;
506
   				}
507
   			}
508
   			//TODO khouzam must set rm.setdata()
509
   			rm.done();
510
   			return;
511
   		}
512
513
   		// When it is not an attach session, it gets a little more complicated
514
   		// so let's use a sequence.
515
   		ImmediateExecutor.getInstance().execute(new StartOrRestartProcessSequence(containerDmc, attributes, restart, rm));
516
    }
517
518
    /**
519
     * This method indicates if we should use the -exec-continue method
520
     * instead of the -exec-run method.
521
     * This can be overridden to allow for customization.
522
     */
523
    protected boolean useContinueCommand(Map<String, Object> attributes, boolean restart) {
524
    	// When doing remote debugging, we use -exec-continue instead of -exec-run
525
    	// Restart does not apply to remote sessions
526
    	return fBackend.getSessionType() == SessionType.REMOTE;
527
    }
528
}
529
(-)src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java (+7 lines)
Lines 27-32 Link Here
27
import org.eclipse.cdt.dsf.gdb.service.command.CommandFactory_6_8;
27
import org.eclipse.cdt.dsf.gdb.service.command.CommandFactory_6_8;
28
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl;
28
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl;
29
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0;
29
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0;
30
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2;
30
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
31
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
31
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
32
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
32
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
33
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
Lines 100-105 Link Here
100
	}
101
	}
101
	
102
	
102
	protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) {
103
	protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) {
104
		if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
105
			return new GDBControl_7_2(session, config, new CommandFactory_6_8());
106
		}
103
		if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
107
		if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
104
			return new GDBControl_7_0(session, config, new CommandFactory_6_8());
108
			return new GDBControl_7_0(session, config, new CommandFactory_6_8());
105
		}
109
		}
Lines 139-144 Link Here
139
		
143
		
140
	@Override
144
	@Override
141
	protected IProcesses createProcessesService(DsfSession session) {
145
	protected IProcesses createProcessesService(DsfSession session) {
146
		if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
147
			return new GDBProcesses_7_2(session);
148
		}
142
		if (GDB_7_1_VERSION.compareTo(fVersion) <= 0) {
149
		if (GDB_7_1_VERSION.compareTo(fVersion) <= 0) {
143
			return new GDBProcesses_7_1(session);
150
			return new GDBProcesses_7_1(session);
144
		}
151
		}
(-)src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_2.java (+37 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2010 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 features in DSF Reference implementation
11
 *     Ericsson           - New version for 7_0
12
 *     Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
13
 *     Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
14
 *******************************************************************************/
15
package org.eclipse.cdt.dsf.gdb.service.command;
16
17
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
18
import org.eclipse.cdt.dsf.service.DsfSession;
19
import org.eclipse.debug.core.ILaunchConfiguration;
20
21
/**
22
 * GDB Debugger control implementation.  This implementation extends the 
23
 * base MI control implementation to provide the GDB-specific debugger 
24
 * features.  This includes:<br>
25
 * - CLI console support,<br>
26
 * - inferior process status tracking.<br>
27
 * @since 4.0
28
 */
29
public class GDBControl_7_2 extends GDBControl_7_0 implements IGDBControl {
30
    /**
31
     * @since 3.0
32
     */
33
    public GDBControl_7_2(DsfSession session, ILaunchConfiguration config, CommandFactory factory) {
34
    	super(session, config, factory);
35
    	setUseThreadGroupOptions(true);
36
    }
37
}
(-)src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java (-9 / +45 lines)
Lines 40-45 Link Here
40
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
40
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
41
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
41
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
42
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
42
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
43
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
43
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
44
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
44
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
45
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
45
import org.eclipse.cdt.dsf.mi.service.command.commands.RawCommand;
46
import org.eclipse.cdt.dsf.mi.service.command.commands.RawCommand;
Lines 86-91 Link Here
86
    private int fCurrentStackLevel  = -1;
87
    private int fCurrentStackLevel  = -1;
87
    private String fCurrentThreadId = null;
88
    private String fCurrentThreadId = null;
88
    
89
    
90
    // boolean for --thread-group option which helps to handle multiple inferior behaviour.
91
    // Since GDB.7.1
92
    private boolean fUseThreadGroupOption;
89
    
93
    
90
    private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
94
    private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
91
    private final Map<Integer, CommandHandle>  fRxCommands = Collections.synchronizedMap(new HashMap<Integer, CommandHandle>());
95
    private final Map<Integer, CommandHandle>  fRxCommands = Collections.synchronizedMap(new HashMap<Integer, CommandHandle>());
Lines 124-140 Link Here
124
    private CommandFactory fCommandFactory;
128
    private CommandFactory fCommandFactory;
125
    
129
    
126
    public AbstractMIControl(DsfSession session) {
130
    public AbstractMIControl(DsfSession session) {
127
        super(session);
131
    	this(session, false, false, new CommandFactory());
128
        fUseThreadAndFrameOptions = false;
129
        fCommandFactory = new CommandFactory();
130
    }
132
    }
131
133
132
    /**
134
    /**
133
     * @since 3.0
135
     * @since 3.0
134
     */
136
     */
135
    public AbstractMIControl(DsfSession session, boolean useThreadAndFrameOptions, CommandFactory factory) {
137
    public AbstractMIControl(DsfSession session, boolean useThreadAndFrameOptions, CommandFactory factory) {
138
    	this(session, false, useThreadAndFrameOptions, factory);
139
    }
140
141
    /**
142
	 * @since 4.0
143
	 */
144
    public AbstractMIControl(DsfSession session, boolean useThreadGroupOption, boolean useThreadAndFrameOptions, CommandFactory factory) {
136
        super(session);
145
        super(session);
146
        
147
        // If we use the --thread-group option, we should automatically use the --thread option
148
        assert useThreadGroupOption ? useThreadAndFrameOptions : true;
149
        
150
        fUseThreadGroupOption     = useThreadGroupOption;
137
        fUseThreadAndFrameOptions = useThreadAndFrameOptions;
151
        fUseThreadAndFrameOptions = useThreadAndFrameOptions;
152
        if (fUseThreadGroupOption) {
153
        	// If we use --thread-group option, we should automatically use the --thread option
154
        	fUseThreadAndFrameOptions = true;
155
        }
138
        fCommandFactory = factory;
156
        fCommandFactory = factory;
139
    }
157
    }
140
158
Lines 163-169 Link Here
163
    protected void setUseThreadAndFrameOptions(boolean shouldUse) {
181
    protected void setUseThreadAndFrameOptions(boolean shouldUse) {
164
    	fUseThreadAndFrameOptions = shouldUse;
182
    	fUseThreadAndFrameOptions = shouldUse;
165
    }
183
    }
166
    
184
    /**
185
	 * @since 4.0
186
	 */
187
    protected void setUseThreadGroupOptions(boolean shouldUse) {
188
    	fUseThreadGroupOption = shouldUse;
189
    	if (shouldUse) {
190
    		fUseThreadAndFrameOptions = true;
191
    	}
192
    }
167
    /**
193
    /**
168
     * @since 3.0
194
     * @since 3.0
169
     */
195
     */
Lines 510-515 Link Here
510
        	return null;
536
        	return null;
511
        } 
537
        } 
512
        
538
        
539
        public String getGroupId() {
540
        	IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IMIContainerDMContext.class);
541
        	if(containerCtx != null)
542
        		return containerCtx.getGroupId();
543
        	return null;
544
        } 
545
        
513
        @Override
546
        @Override
514
        public String toString() {
547
        public String toString() {
515
            return Integer.toString(fTokenId) + fCommand;
548
            return Integer.toString(fTokenId) + fCommand;
Lines 567-579 Link Here
567
                 */
600
                 */
568
601
569
                final String str;
602
                final String str;
570
				// Not all commands support the --thread/--frame options (e.g., CLI commands)
603
                if (commandHandle.getCommand() instanceof RawCommand) {
571
                if (fUseThreadAndFrameOptions && commandHandle.getCommand().supportsThreadAndFrameOptions()) {
572
                	str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getThreadId(),
573
                			                                                                       commandHandle.getStackFrameId());
574
                } else if (commandHandle.getCommand() instanceof RawCommand) {
575
                	// RawCommands CANNOT have a token id: GDB would read it as part of the RawCommand!
604
                	// RawCommands CANNOT have a token id: GDB would read it as part of the RawCommand!
576
                	str = commandHandle.getCommand().constructCommand();
605
                	str = commandHandle.getCommand().constructCommand();
606
                } else if (fUseThreadGroupOption) {
607
                	str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getGroupId(),
608
							   																	   commandHandle.getThreadId(),
609
							   																	   commandHandle.getStackFrameId());                	
610
                } else if (fUseThreadAndFrameOptions) {
611
                	str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getThreadId(),
612
							   																	   commandHandle.getStackFrameId());
577
                } else {
613
                } else {
578
                	str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand();
614
                	str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand();
579
                }
615
                }
(-)src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java (-2 / +23 lines)
Lines 28-33 Link Here
28
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
28
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
29
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
29
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
30
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
30
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
31
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
31
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
32
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
32
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
33
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
33
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
34
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
Lines 525-535 Link Here
525
		return new MIExecUntil(dmc, loc);
526
		return new MIExecUntil(dmc, loc);
526
	}
527
	}
527
528
528
	public ICommand<MIInfo> createMIFileExecAndSymbols(ICommandControlDMContext dmc, String file) {
529
	/**
530
	 * @since 4.0
531
	 */
532
	public ICommand<MIInfo> createMIFileExecAndSymbols(IMIContainerDMContext dmc, String file) {
529
		return new MIFileExecAndSymbols(dmc, file);
533
		return new MIFileExecAndSymbols(dmc, file);
530
	}
534
	}
531
535
532
	public ICommand<MIInfo> createMIFileExecAndSymbols(ICommandControlDMContext dmc) {
536
	/**
537
	 * @since 4.0
538
	 */
539
	public ICommand<MIInfo> createMIFileExecAndSymbols(IMIContainerDMContext dmc) {
533
		return new MIFileExecAndSymbols(dmc);
540
		return new MIFileExecAndSymbols(dmc);
534
	}
541
	}
535
542
Lines 686-695 Link Here
686
		return new MITargetAttach(ctx, groupId);
693
		return new MITargetAttach(ctx, groupId);
687
	}
694
	}
688
695
696
	/**
697
	 * @since 4.0
698
	 */
699
	public ICommand<MIInfo> createMITargetAttach(IMIContainerDMContext ctx, String groupId) {
700
		return new MITargetAttach(ctx, groupId);
701
	}
702
689
	public ICommand<MIInfo> createMITargetDetach(ICommandControlDMContext ctx, String groupId) {
703
	public ICommand<MIInfo> createMITargetDetach(ICommandControlDMContext ctx, String groupId) {
690
		return new MITargetDetach(ctx, groupId);
704
		return new MITargetDetach(ctx, groupId);
691
	}
705
	}
692
706
707
	/**
708
	 * @since 4.0
709
	 */
710
	public ICommand<MIInfo> createMITargetDetach(IMIContainerDMContext ctx) {
711
		return new MITargetDetach(ctx);
712
	}
713
693
    public ICommand<MIInfo> createMITargetSelect(IDMContext ctx, String[] params) {
714
    public ICommand<MIInfo> createMITargetSelect(IDMContext ctx, String[] params) {
694
        return new MITargetSelect(ctx, params);
715
        return new MITargetSelect(ctx, params);
695
    }
716
    }
(-)src/org/eclipse/cdt/dsf/mi/service/command/commands/MICommand.java (-2 / +16 lines)
Lines 141-156 Link Here
141
     * @since 1.1
141
     * @since 1.1
142
     */
142
     */
143
    public String constructCommand(String threadId, int frameId) {
143
    public String constructCommand(String threadId, int frameId) {
144
    	return constructCommand(null, threadId, frameId);
145
    }
146
147
    /**
148
     * GDB 7.2 thread-group needed to support multiple behaviour.
149
     * @since 4.0
150
     */
151
    public String constructCommand(String groupId, String threadId, int frameId) {
144
        StringBuffer command = new StringBuffer(getOperation());
152
        StringBuffer command = new StringBuffer(getOperation());
145
        
153
        
146
        // Add the --thread option
154
        // Add the --thread option
147
        if (threadId != null) {
155
        if (supportsThreadAndFrameOptions() && threadId != null) {
148
        	command.append(" --thread " + threadId); //$NON-NLS-1$
156
        	command.append(" --thread " + threadId); //$NON-NLS-1$
149
157
150
        	// Add the --frame option, but only if we are using the --thread option
158
        	// Add the --frame option, but only if we are using the --thread option
151
        	if (frameId >= 0) {
159
        	if (frameId >= 0) {
152
        		command.append(" --frame " + frameId); //$NON-NLS-1$
160
        		command.append(" --frame " + frameId); //$NON-NLS-1$
153
        	}
161
        	}
162
        } else if (supportsThreadGroupOption() && groupId != null) {
163
        	command.append(" --thread-group " + groupId); //$NON-NLS-1$
154
        }
164
        }
155
165
156
        String opt = optionsToString();
166
        String opt = optionsToString();
Lines 164-170 Link Here
164
        command.append('\n');
174
        command.append('\n');
165
        return command.toString();
175
        return command.toString();
166
    }
176
    }
167
    
168
//    /*
177
//    /*
169
//     * Checks to see if the current command can be coalesced with the 
178
//     * Checks to see if the current command can be coalesced with the 
170
//     * supplied command.
179
//     * supplied command.
Lines 241-246 Link Here
241
     * @since 1.1
250
     * @since 1.1
242
     */
251
     */
243
    public boolean supportsThreadAndFrameOptions() { return true; }
252
    public boolean supportsThreadAndFrameOptions() { return true; }
253
254
    /**
255
     * @since 4.0
256
     */
257
    public boolean supportsThreadGroupOption() { return false; }
244
    
258
    
245
    /**
259
    /**
246
     * Compare commands based on the MI command string that they generate, 
260
     * Compare commands based on the MI command string that they generate, 
(-)src/org/eclipse/cdt/dsf/mi/service/command/commands/MIFileExecAndSymbols.java (-5 / +12 lines)
Lines 11-17 Link Here
11
11
12
package org.eclipse.cdt.dsf.mi.service.command.commands;
12
package org.eclipse.cdt.dsf.mi.service.command.commands;
13
13
14
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
14
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
15
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
15
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
16
16
17
/**
17
/**
Lines 26-41 Link Here
26
public class MIFileExecAndSymbols extends MICommand<MIInfo>
26
public class MIFileExecAndSymbols extends MICommand<MIInfo>
27
{
27
{
28
    /**
28
    /**
29
     * @since 1.1
29
     * @since 4.0
30
     */
30
     */
31
    public MIFileExecAndSymbols(ICommandControlDMContext dmc, String file) {
31
    public MIFileExecAndSymbols(IMIContainerDMContext dmc, String file) {
32
        super(dmc, "-file-exec-and-symbols", null, new String[] {file}); //$NON-NLS-1$
32
        super(dmc, "-file-exec-and-symbols", null, new String[] {file}); //$NON-NLS-1$
33
    }
33
    }
34
   
34
   
35
    /**
35
    /**
36
     * @since 1.1
36
     * @since 4.0
37
     */
37
     */
38
    public MIFileExecAndSymbols(ICommandControlDMContext dmc) {
38
    public MIFileExecAndSymbols(IMIContainerDMContext dmc) {
39
        super(dmc, "-file-exec-and-symbols"); //$NON-NLS-1$
39
        super(dmc, "-file-exec-and-symbols"); //$NON-NLS-1$
40
    }
40
    }
41
42
    @Override
43
    public boolean supportsThreadGroupOption() {
44
    	return true;
45
    }
46
    
47
    
41
}
48
}
(-)src/org/eclipse/cdt/dsf/mi/service/command/commands/MITargetAttach.java (-1 / +19 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2008, 2009 Ericsson and others.
2
 * Copyright (c) 2008, 2010 Ericsson and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 11-16 Link Here
11
package org.eclipse.cdt.dsf.mi.service.command.commands;
11
package org.eclipse.cdt.dsf.mi.service.command.commands;
12
12
13
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
13
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
14
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
14
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
15
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
15
16
16
/**
17
/**
Lines 25-28 Link Here
25
	public MITargetAttach(ICommandControlDMContext ctx, String groupId) {
26
	public MITargetAttach(ICommandControlDMContext ctx, String groupId) {
26
		super(ctx, "-target-attach", new String[] {groupId}); //$NON-NLS-1$
27
		super(ctx, "-target-attach", new String[] {groupId}); //$NON-NLS-1$
27
	}
28
	}
29
	
30
	/**
31
	 * @since 4.0
32
	 */
33
	/*
34
	public MITargetAttach(IMIContainerDMContext ctx, String pid) {
35
		super(ctx, "-target-attach", new String[] {"--thread-group", ctx.getGroupId()}, new String[] {pid}); //$NON-NLS-1$ //$NON-NLS-2$
36
	}
37
	*/
38
	public MITargetAttach(IMIContainerDMContext ctx, String pid) {
39
		super(ctx, "-target-attach", new String[] {pid}); //$NON-NLS-1$
40
	}
41
	
42
    @Override
43
    public boolean supportsThreadGroupOption() {
44
    	return true;
45
    }
28
}
46
}
(-)src/org/eclipse/cdt/dsf/mi/service/command/commands/MITargetDetach.java (+8 lines)
Lines 11-16 Link Here
11
package org.eclipse.cdt.dsf.mi.service.command.commands;
11
package org.eclipse.cdt.dsf.mi.service.command.commands;
12
12
13
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
13
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
14
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
14
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
15
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
15
16
16
/**
17
/**
Lines 25-28 Link Here
25
	public MITargetDetach(ICommandControlDMContext ctx, String groupId) {
26
	public MITargetDetach(ICommandControlDMContext ctx, String groupId) {
26
		super(ctx, "-target-detach", new String[] {groupId}); //$NON-NLS-1$
27
		super(ctx, "-target-detach", new String[] {groupId}); //$NON-NLS-1$
27
	}
28
	}
29
	
30
	/**
31
	* @since 4.0
32
	*/
33
	public MITargetDetach(IMIContainerDMContext ctx) {
34
		super(ctx, "-target-detach", new String[] {"--thread-group", ctx.getGroupId()}); //$NON-NLS-1$ //$NON-NLS-2$
35
	}
28
}
36
}
(-)src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java (-1 / +1 lines)
Lines 159-165 Link Here
159
            fResumeWithoutSignalCommand = new GdbResumeWithoutSignalCommand(session);
159
            fResumeWithoutSignalCommand = new GdbResumeWithoutSignalCommand(session);
160
            fRestartCommand = new GdbRestartCommand(session, fLaunch);
160
            fRestartCommand = new GdbRestartCommand(session, fLaunch);
161
            fTerminateCommand = new DsfTerminateCommand(session);
161
            fTerminateCommand = new DsfTerminateCommand(session);
162
            fConnectCommand = new GdbConnectCommand(session);
162
            fConnectCommand = new GdbConnectCommand(session, fLaunch);
163
            fDisconnectCommand = new GdbDisconnectCommand(session);
163
            fDisconnectCommand = new GdbDisconnectCommand(session);
164
            fSuspendTrigger = new GdbSuspendTrigger(session, fLaunch);
164
            fSuspendTrigger = new GdbSuspendTrigger(session, fLaunch);
165
            fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory();
165
            fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory();
(-)src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbConnectCommand.java (-1 / +46 lines)
Lines 11-17 Link Here
11
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
11
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.HashMap;
14
import java.util.List;
15
import java.util.List;
16
import java.util.Map;
15
import java.util.concurrent.ExecutionException;
17
import java.util.concurrent.ExecutionException;
16
import java.util.concurrent.RejectedExecutionException;
18
import java.util.concurrent.RejectedExecutionException;
17
19
Lines 42-56 Link Here
42
import org.eclipse.core.runtime.jobs.Job;
44
import org.eclipse.core.runtime.jobs.Job;
43
import org.eclipse.debug.core.DebugPlugin;
45
import org.eclipse.debug.core.DebugPlugin;
44
import org.eclipse.debug.core.IStatusHandler;
46
import org.eclipse.debug.core.IStatusHandler;
47
import org.eclipse.debug.core.Launch;
48
import org.eclipse.swt.SWT;
49
import org.eclipse.swt.widgets.Display;
50
import org.eclipse.swt.widgets.FileDialog;
51
import org.eclipse.swt.widgets.Shell;
52
import org.eclipse.ui.PlatformUI;
45
53
46
public class GdbConnectCommand implements IConnect {
54
public class GdbConnectCommand implements IConnect {
47
    
55
    
48
	private final DsfExecutor fExecutor;
56
	private final DsfExecutor fExecutor;
49
    private final DsfServicesTracker fTracker;
57
    private final DsfServicesTracker fTracker;
58
    private final Launch fLaunch;
50
    
59
    
51
    public GdbConnectCommand(DsfSession session) {
60
    public GdbConnectCommand(DsfSession session, Launch launch) {
52
        fExecutor = session.getExecutor();
61
        fExecutor = session.getExecutor();
53
        fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
62
        fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
63
        fLaunch = launch;
54
    }    
64
    }    
55
65
56
    public void dispose() {
66
    public void dispose() {
Lines 115-120 Link Here
115
    		} 				
125
    		} 				
116
126
117
    		try {
127
    		try {
128
    			// Add an entry to create a new process
129
    			IProcessExtendedInfo[] newArray = new IProcessExtendedInfo[fProcessList.length + 1];
130
    			System.arraycopy(fProcessList, 0, newArray, 1, fProcessList.length);
131
    			newArray[0] = new ProcessInfo(-1, "! <Create new process> !");
132
    			fProcessList = newArray;
133
118
    			Object result = prompter.handleStatus(processPromptStatus, fProcessList);
134
    			Object result = prompter.handleStatus(processPromptStatus, fProcessList);
119
    			if (result instanceof Integer) {
135
    			if (result instanceof Integer) {
120
    				fRequestMonitor.setData((Integer)result);
136
    				fRequestMonitor.setData((Integer)result);
Lines 172-180 Link Here
172
															// New cycle, look for service again
188
															// New cycle, look for service again
173
															final IMIProcesses procService = fTracker.getService(IMIProcesses.class);
189
															final IMIProcesses procService = fTracker.getService(IMIProcesses.class);
174
															if (procService != null) {
190
															if (procService != null) {
191
																if (getData() == -1) {
192
																	// We want to create a new process instead
193
																	Map<String, Object> attributes = new HashMap<String, Object>();
194
																	try {
195
																		attributes = fLaunch.getLaunchConfiguration().getAttributes();
196
																	} catch (CoreException e) {
197
																	}
198
																	final String[] binaryPath = new String[1];
199
200
																	PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
201
																		public void run() {
202
																	   		Shell shell = Display.getDefault().getActiveShell();		
203
																    		if (shell == null) {
204
																    			return;
205
																    		}
206
207
																    		FileDialog fd = new FileDialog(shell, SWT.SAVE);
208
																    		binaryPath[0] = fd.open();
209
																    	}
210
																	});
211
																	procService.debugNewProcess(controlCtx, 
212
																			                    binaryPath[0],
213
																			                    attributes, 
214
																			                    new DataRequestMonitor<IDMContext>(fExecutor, rm));
215
																	return;
216
																}
217
																
175
																IProcessDMContext procDmc = procService.createProcessContext(controlCtx,
218
																IProcessDMContext procDmc = procService.createProcessContext(controlCtx,
176
																		Integer.toString(getData()));
219
																		Integer.toString(getData()));
177
																procService.attachDebuggerToProcess(procDmc, new DataRequestMonitor<IDMContext>(fExecutor, rm));
220
																procService.attachDebuggerToProcess(procDmc, new DataRequestMonitor<IDMContext>(fExecutor, rm));
221
															} else {
222
																rm.done();
178
															}
223
															}
179
														}
224
														}
180
													}).schedule();
225
													}).schedule();

Return to bug 237306