author | l12wang |
Mon, 23 Nov 2009 00:59:16 -0600 | |
changeset 117 | 09f3d307f081 |
parent 37 | c2bce6dd59e7 |
child 122 | d94b9ba55bed |
permissions | -rw-r--r-- |
37 | 1 |
/******************************************************************************* |
2 |
* Copyright (c) 2007, 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 |
||
12 |
package org.eclipse.cdt.dsf.mi.service; |
|
13 |
||
14 |
import java.util.HashMap; |
|
15 |
import java.util.Hashtable; |
|
16 |
import java.util.Map; |
|
17 |
||
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
18 |
import org.eclipse.cdt.debug.core.CDebugCorePlugin; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
19 |
import org.eclipse.cdt.debug.core.model.ICBreakpoint; |
37 | 20 |
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; |
21 |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; |
|
22 |
import org.eclipse.cdt.dsf.concurrent.Immutable; |
|
23 |
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; |
|
24 |
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext; |
|
25 |
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; |
|
26 |
import org.eclipse.cdt.dsf.datamodel.DMContexts; |
|
27 |
import org.eclipse.cdt.dsf.datamodel.IDMContext; |
|
28 |
import org.eclipse.cdt.dsf.debug.service.IBreakpoints; |
|
29 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; |
|
30 |
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent; |
|
31 |
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
32 |
import org.eclipse.cdt.dsf.mi.service.MIRunControl.SuspendedEvent; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
33 |
import org.eclipse.cdt.dsf.mi.service.breakpoint.actions.BreakpointActionAdapter; |
37 | 34 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter; |
35 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCondition; |
|
36 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete; |
|
37 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDisable; |
|
38 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakEnable; |
|
39 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert; |
|
40 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakList; |
|
41 |
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakWatch; |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
42 |
import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent; |
37 | 43 |
import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointScopeEvent; |
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
44 |
import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointTriggerEvent; |
37 | 45 |
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; |
46 |
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo; |
|
47 |
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint; |
|
48 |
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; |
|
49 |
import org.eclipse.cdt.dsf.service.AbstractDsfService; |
|
50 |
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; |
|
51 |
import org.eclipse.cdt.dsf.service.DsfSession; |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
52 |
import org.eclipse.core.runtime.CoreException; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
53 |
import org.eclipse.core.runtime.IProgressMonitor; |
37 | 54 |
import org.eclipse.core.runtime.IStatus; |
55 |
import org.eclipse.core.runtime.Status; |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
56 |
import org.eclipse.core.runtime.jobs.Job; |
37 | 57 |
import org.osgi.framework.BundleContext; |
58 |
||
59 |
/** |
|
60 |
* Initial breakpoint service implementation. |
|
61 |
* Implements the IBreakpoints interface. |
|
62 |
*/ |
|
63 |
public class MIBreakpoints extends AbstractDsfService implements IBreakpoints |
|
64 |
{ |
|
65 |
/** |
|
66 |
* Breakpoint attributes markers used in the map parameters of insert/updateBreakpoint(). |
|
67 |
* All are optional with the possible exception of TYPE. It is the responsibility of the |
|
68 |
* service to ensure that the set of attributes provided is sufficient to create/update |
|
69 |
* a valid breakpoint on the back-end. |
|
70 |
*/ |
|
71 |
public static final String PREFIX = "org.eclipse.cdt.dsf.debug.breakpoint"; //$NON-NLS-1$ |
|
72 |
||
73 |
// General markers |
|
74 |
public static final String BREAKPOINT_TYPE = PREFIX + ".type"; //$NON-NLS-1$ |
|
75 |
public static final String BREAKPOINT = "breakpoint"; //$NON-NLS-1$ |
|
76 |
public static final String WATCHPOINT = "watchpoint"; //$NON-NLS-1$ |
|
77 |
public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ |
|
78 |
||
79 |
// Basic set of breakpoint attribute markers |
|
80 |
public static final String FILE_NAME = PREFIX + ".fileName"; //$NON-NLS-1$ |
|
81 |
public static final String LINE_NUMBER = PREFIX + ".lineNumber"; //$NON-NLS-1$ |
|
82 |
public static final String FUNCTION = PREFIX + ".function"; //$NON-NLS-1$ |
|
83 |
public static final String ADDRESS = PREFIX + ".address"; //$NON-NLS-1$ |
|
84 |
public static final String CONDITION = PREFIX + ".condition"; //$NON-NLS-1$ |
|
85 |
public static final String IGNORE_COUNT = PREFIX + ".ignoreCount"; //$NON-NLS-1$ |
|
86 |
public static final String IS_ENABLED = PREFIX + ".isEnabled"; //$NON-NLS-1$ |
|
87 |
||
88 |
// Basic set of watchpoint attribute markers |
|
89 |
public static final String EXPRESSION = PREFIX + ".expression"; //$NON-NLS-1$ |
|
90 |
public static final String READ = PREFIX + ".read"; //$NON-NLS-1$ |
|
91 |
public static final String WRITE = PREFIX + ".write"; //$NON-NLS-1$ |
|
92 |
||
93 |
// Services |
|
94 |
ICommandControl fConnection; |
|
95 |
||
96 |
// Service breakpoints tracking |
|
97 |
// The breakpoints are stored per context and keyed on the back-end breakpoint reference |
|
98 |
private Map<IBreakpointsTargetDMContext, Map<Integer, MIBreakpointDMData>> fBreakpoints = |
|
99 |
new HashMap<IBreakpointsTargetDMContext, Map<Integer, MIBreakpointDMData>>(); |
|
100 |
||
101 |
// Error messages |
|
102 |
final String NULL_STRING = ""; //$NON-NLS-1$ |
|
103 |
final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context"; //$NON-NLS-1$ |
|
104 |
final String UNKNOWN_BREAKPOINT_CONTEXT = "Unknown breakpoint context"; //$NON-NLS-1$ |
|
105 |
final String UNKNOWN_BREAKPOINT_TYPE = "Unknown breakpoint type"; //$NON-NLS-1$ |
|
106 |
final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; //$NON-NLS-1$ |
|
107 |
final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure"; //$NON-NLS-1$ |
|
108 |
final String WATCHPOINT_INSERTION_FAILURE = "Watchpoint insertion failure"; //$NON-NLS-1$ |
|
109 |
final String INVALID_CONDITION = "Invalid condition"; //$NON-NLS-1$ |
|
110 |
||
111 |
||
112 |
/////////////////////////////////////////////////////////////////////////// |
|
113 |
// Breakpoint Events |
|
114 |
/////////////////////////////////////////////////////////////////////////// |
|
115 |
||
116 |
public class BreakpointsChangedEvent extends AbstractDMEvent<IBreakpointsTargetDMContext> implements IBreakpointsChangedEvent { |
|
117 |
private IBreakpointDMContext[] fEventBreakpoints; |
|
118 |
||
119 |
public BreakpointsChangedEvent(IBreakpointDMContext bp) { |
|
120 |
super(DMContexts.getAncestorOfType(bp, IBreakpointsTargetDMContext.class)); |
|
121 |
fEventBreakpoints = new IBreakpointDMContext[] { bp }; |
|
122 |
} |
|
123 |
public IBreakpointDMContext[] getBreakpoints() { |
|
124 |
return fEventBreakpoints; |
|
125 |
} |
|
126 |
} |
|
127 |
||
128 |
public class BreakpointAddedEvent extends BreakpointsChangedEvent implements IBreakpointsAddedEvent { |
|
129 |
public BreakpointAddedEvent(IBreakpointDMContext context) { |
|
130 |
super(context); |
|
131 |
} |
|
132 |
} |
|
133 |
||
134 |
public class BreakpointUpdatedEvent extends BreakpointsChangedEvent implements IBreakpointsUpdatedEvent { |
|
135 |
public BreakpointUpdatedEvent(IBreakpointDMContext context) { |
|
136 |
super(context); |
|
137 |
} |
|
138 |
} |
|
139 |
||
140 |
public class BreakpointRemovedEvent extends BreakpointsChangedEvent implements IBreakpointsRemovedEvent { |
|
141 |
public BreakpointRemovedEvent(IBreakpointDMContext context) { |
|
142 |
super(context); |
|
143 |
} |
|
144 |
} |
|
145 |
||
146 |
/////////////////////////////////////////////////////////////////////////// |
|
147 |
// IBreakpointDMContext |
|
148 |
// Used to hold the back-end breakpoint references. The reference can then |
|
149 |
// be used to get the actual DsfMIBreakpoint. |
|
150 |
/////////////////////////////////////////////////////////////////////////// |
|
151 |
@Immutable |
|
152 |
public static final class MIBreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext { |
|
153 |
||
154 |
// The breakpoint reference |
|
155 |
private final Integer fReference; |
|
156 |
||
157 |
/** |
|
158 |
* @param service the Breakpoint service |
|
159 |
* @param parents the parent contexts |
|
160 |
* @param reference the DsfMIBreakpoint reference |
|
161 |
*/ |
|
162 |
public MIBreakpointDMContext(MIBreakpoints service, IDMContext[] parents, int reference) { |
|
163 |
super(service.getSession().getId(), parents); |
|
164 |
fReference = reference; |
|
165 |
} |
|
166 |
||
167 |
/* (non-Javadoc) |
|
168 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints.IDsfBreakpointDMContext#getReference() |
|
169 |
*/ |
|
170 |
public int getReference() { |
|
171 |
return fReference; |
|
172 |
} |
|
173 |
||
174 |
/* (non-Javadoc) |
|
175 |
* @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object) |
|
176 |
*/ |
|
177 |
@Override |
|
178 |
public boolean equals(Object obj) { |
|
179 |
return baseEquals(obj) && (fReference == ((MIBreakpointDMContext) obj).fReference); |
|
180 |
} |
|
181 |
||
182 |
/* (non-Javadoc) |
|
183 |
* @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#hashCode() |
|
184 |
*/ |
|
185 |
@Override |
|
186 |
public int hashCode() { |
|
187 |
return baseHashCode() + fReference.hashCode(); |
|
188 |
} |
|
189 |
||
190 |
/* (non-Javadoc) |
|
191 |
* @see java.lang.Object#toString() |
|
192 |
*/ |
|
193 |
@Override |
|
194 |
public String toString() { |
|
195 |
return baseToString() + ".reference(" + fReference + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ |
|
196 |
} |
|
197 |
} |
|
198 |
||
199 |
/////////////////////////////////////////////////////////////////////////// |
|
200 |
// AbstractDsfService |
|
201 |
/////////////////////////////////////////////////////////////////////////// |
|
202 |
||
203 |
/** |
|
204 |
* The service constructor |
|
205 |
* |
|
206 |
* @param session The debugging session |
|
207 |
*/ |
|
208 |
public MIBreakpoints(DsfSession session) { |
|
209 |
super(session); |
|
210 |
} |
|
211 |
||
212 |
/* (non-Javadoc) |
|
213 |
* @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor) |
|
214 |
*/ |
|
215 |
@Override |
|
216 |
public void initialize(final RequestMonitor rm) { |
|
217 |
super.initialize(new RequestMonitor(getExecutor(), rm) { |
|
218 |
@Override |
|
219 |
protected void handleSuccess() { |
|
220 |
doInitialize(rm); |
|
221 |
} |
|
222 |
}); |
|
223 |
} |
|
224 |
||
225 |
/* |
|
226 |
* Asynchronous service initialization |
|
227 |
*/ |
|
228 |
private void doInitialize(final RequestMonitor rm) { |
|
229 |
||
230 |
// Get the services references |
|
231 |
fConnection = getServicesTracker().getService(ICommandControl.class); |
|
232 |
||
233 |
// Register for the useful events |
|
234 |
getSession().addServiceEventListener(this, null); |
|
235 |
||
236 |
// Register this service |
|
237 |
register(new String[] { IBreakpoints.class.getName(), MIBreakpoints.class.getName() }, |
|
238 |
new Hashtable<String, String>()); |
|
239 |
||
240 |
rm.done(); |
|
241 |
} |
|
242 |
||
243 |
/* (non-Javadoc) |
|
244 |
* @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor) |
|
245 |
*/ |
|
246 |
@Override |
|
247 |
public void shutdown(final RequestMonitor rm) { |
|
248 |
unregister(); |
|
249 |
getSession().removeServiceEventListener(this); |
|
250 |
rm.done(); |
|
251 |
} |
|
252 |
||
253 |
/* (non-Javadoc) |
|
254 |
* @see org.eclipse.cdt.dsf.service.AbstractDsfService#getBundleContext() |
|
255 |
*/ |
|
256 |
@Override |
|
257 |
protected BundleContext getBundleContext() { |
|
258 |
return GdbPlugin.getBundleContext(); |
|
259 |
} |
|
260 |
||
261 |
/////////////////////////////////////////////////////////////////////////// |
|
262 |
// IServiceEventListener |
|
263 |
/////////////////////////////////////////////////////////////////////////// |
|
264 |
||
265 |
/** |
|
266 |
* This method is left for API compatibility only. |
|
267 |
* @nooverride This method is not intended to be re-implemented or extended by clients. |
|
268 |
* @noreference This method is not intended to be referenced by clients. |
|
269 |
*/ |
|
270 |
@DsfServiceEventHandler |
|
271 |
public void eventDispatched(MIWatchpointScopeEvent e) { |
|
272 |
// When a watchpoint goes out of scope, it is automatically removed from |
|
273 |
// the back-end. To keep our internal state synchronized, we have to |
|
274 |
// remove it from our breakpoints map. |
|
275 |
IBreakpointsTargetDMContext bpContext = DMContexts.getAncestorOfType(e.getDMContext(), IBreakpointsTargetDMContext.class); |
|
276 |
if (bpContext != null) { |
|
277 |
Map<Integer, MIBreakpointDMData> contextBps = fBreakpoints.get(bpContext); |
|
278 |
if (contextBps != null) { |
|
279 |
contextBps.remove(e.getNumber()); |
|
280 |
} |
|
281 |
} |
|
282 |
} |
|
283 |
||
284 |
/** |
|
285 |
* @since 1.1 |
|
286 |
* @nooverride This method is not intended to be re-implemented or extended by clients. |
|
287 |
* @noreference This method is not intended to be referenced by clients. |
|
288 |
*/ |
|
289 |
@DsfServiceEventHandler |
|
290 |
public void eventDispatched(ICommandControlShutdownDMEvent e) { |
|
291 |
} |
|
292 |
||
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
293 |
@DsfServiceEventHandler |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
294 |
public void eventDispatched(SuspendedEvent e) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
295 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
296 |
if (e.getMIEvent() instanceof MIBreakpointHitEvent) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
297 |
MIBreakpointHitEvent evt = (MIBreakpointHitEvent) e.getMIEvent(); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
298 |
performBreakpointAction(evt.getDMContext(), evt.getNumber()); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
299 |
return; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
300 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
301 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
302 |
if (e.getMIEvent() instanceof MIWatchpointTriggerEvent) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
303 |
MIWatchpointTriggerEvent evt = (MIWatchpointTriggerEvent) e.getMIEvent(); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
304 |
performBreakpointAction(evt.getDMContext(), evt.getNumber()); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
305 |
return; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
306 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
307 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
308 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
309 |
private void performBreakpointAction(final IDMContext context, int number) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
310 |
// Identify the platform breakpoint |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
311 |
final ICBreakpoint breakpoint = findPlatformBreakpoint(context, number); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
312 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
313 |
// Perform the actions asynchronously (otherwise we can have a deadlock...) |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
314 |
new Job("Breakpoint action") { //$NON-NLS-1$ |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
315 |
{ setSystem(true); } |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
316 |
@Override |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
317 |
protected IStatus run(IProgressMonitor monitor) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
318 |
CDebugCorePlugin.getDefault().getBreakpointActionManager().executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context)); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
319 |
return Status.OK_STATUS; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
320 |
}; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
321 |
}.schedule(); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
322 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
323 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
324 |
// Helper function to locate the platform breakpoint corresponding |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
325 |
// to the target breakpoint/watchpoint that was just hit |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
326 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
327 |
// FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
328 |
private ICBreakpoint findPlatformBreakpoint(IDMContext context, int targetBreakpointID) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
329 |
// Hmm, the service has no tracking of MIBreakpointDMContext. So this workaround. |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
330 |
IBreakpointsTargetDMContext btDMC = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
331 |
assert btDMC != null; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
332 |
IBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { btDMC }, targetBreakpointID); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
333 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
334 |
MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
335 |
ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(btDMC, dmc); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
336 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
337 |
return cdtBP; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
338 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
339 |
|
37 | 340 |
/////////////////////////////////////////////////////////////////////////// |
341 |
// IBreakpoints interface |
|
342 |
/////////////////////////////////////////////////////////////////////////// |
|
343 |
||
344 |
//------------------------------------------------------------------------- |
|
345 |
// getBreakpoints |
|
346 |
//------------------------------------------------------------------------- |
|
347 |
||
348 |
/* (non-Javadoc) |
|
349 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints#getBreakpoints(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) |
|
350 |
*/ |
|
351 |
public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor<IBreakpointDMContext[]> drm) |
|
352 |
{ |
|
353 |
// Validate the context |
|
354 |
if (context == null) { |
|
355 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); |
|
356 |
drm.done(); |
|
357 |
return; |
|
358 |
} |
|
359 |
||
360 |
// Select the breakpoints context map |
|
361 |
// If it doesn't exist then no breakpoint was ever inserted for this breakpoint space. |
|
362 |
// In that case, return an empty list. |
|
363 |
final Map<Integer, MIBreakpointDMData> breakpointContext = fBreakpoints.get(context); |
|
364 |
if (breakpointContext == null) { |
|
365 |
drm.setData(new IBreakpointDMContext[0]); |
|
366 |
drm.done(); |
|
367 |
return; |
|
368 |
} |
|
369 |
||
370 |
// Execute the command |
|
371 |
fConnection.queueCommand(new MIBreakList(context), |
|
372 |
new DataRequestMonitor<MIBreakListInfo>(getExecutor(), drm) { |
|
373 |
@Override |
|
374 |
protected void handleSuccess() { |
|
375 |
// Refresh the breakpoints map and format the result |
|
376 |
breakpointContext.clear(); |
|
377 |
MIBreakpoint[] breakpoints = getData().getMIBreakpoints(); |
|
378 |
IBreakpointDMContext[] result = new IBreakpointDMContext[breakpoints.length]; |
|
379 |
for (int i = 0; i < breakpoints.length; i++) { |
|
380 |
MIBreakpointDMData breakpoint = new MIBreakpointDMData(breakpoints[i]); |
|
381 |
int reference = breakpoint.getReference(); |
|
382 |
result[i] = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); |
|
383 |
breakpointContext.put(reference, breakpoint); |
|
384 |
} |
|
385 |
drm.setData(result); |
|
386 |
drm.done(); |
|
387 |
} |
|
388 |
}); |
|
389 |
} |
|
390 |
||
391 |
//------------------------------------------------------------------------- |
|
392 |
// getBreakpointDMData |
|
393 |
//------------------------------------------------------------------------- |
|
394 |
||
395 |
/* (non-Javadoc) |
|
396 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints#getBreakpointDMData(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IDsfBreakpointDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) |
|
397 |
*/ |
|
398 |
public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor<IBreakpointDMData> drm) |
|
399 |
{ |
|
400 |
// Validate the breakpoint context |
|
401 |
if (dmc == null) { |
|
402 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
403 |
drm.done(); |
|
404 |
return; |
|
405 |
} |
|
406 |
||
407 |
// Validate the breakpoint type |
|
408 |
MIBreakpointDMContext breakpoint; |
|
409 |
if (dmc instanceof MIBreakpointDMContext) { |
|
410 |
breakpoint = (MIBreakpointDMContext) dmc; |
|
411 |
} |
|
412 |
else { |
|
413 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); |
|
414 |
drm.done(); |
|
415 |
return; |
|
416 |
} |
|
417 |
||
418 |
// Validate the target context |
|
419 |
IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(breakpoint, IBreakpointsTargetDMContext.class); |
|
420 |
if (context == null) { |
|
421 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); |
|
422 |
drm.done(); |
|
423 |
return; |
|
424 |
} |
|
425 |
||
426 |
// Select the breakpoints context map |
|
427 |
Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
428 |
if (contextBreakpoints == null) { |
|
429 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
430 |
drm.done(); |
|
431 |
return; |
|
432 |
} |
|
433 |
||
434 |
// No need to go to the back-end for this one |
|
435 |
IBreakpointDMData breakpointCopy = new MIBreakpointDMData(contextBreakpoints.get(breakpoint.getReference())); |
|
436 |
drm.setData(breakpointCopy); |
|
437 |
drm.done(); |
|
438 |
} |
|
439 |
||
440 |
//------------------------------------------------------------------------- |
|
441 |
// insertBreakpoint |
|
442 |
//------------------------------------------------------------------------- |
|
443 |
||
444 |
/* (non-Javadoc) |
|
445 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints#insertBreakpoint(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext, java.util.Map, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) |
|
446 |
*/ |
|
447 |
public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) { |
|
448 |
||
449 |
// Validate the context |
|
450 |
if (context == null) { |
|
451 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); |
|
452 |
drm.done(); |
|
453 |
return; |
|
454 |
} |
|
455 |
||
456 |
// Select the breakpoints context map. If it doesn't exist, create it. |
|
457 |
Map<Integer, MIBreakpointDMData> breakpointContext = fBreakpoints.get(context); |
|
458 |
if (breakpointContext == null) { |
|
459 |
breakpointContext = new HashMap<Integer, MIBreakpointDMData>(); |
|
460 |
fBreakpoints.put(context, breakpointContext); |
|
461 |
} |
|
462 |
||
463 |
// Validate the breakpoint type |
|
464 |
String type = (String) attributes.get(BREAKPOINT_TYPE); |
|
465 |
if (type == null) { |
|
466 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); |
|
467 |
drm.done(); |
|
468 |
return; |
|
469 |
} |
|
470 |
||
471 |
// And go... |
|
472 |
if (type.equals(BREAKPOINT)) { |
|
473 |
addBreakpoint(context, attributes, drm); |
|
474 |
} |
|
475 |
else if (type.equals(WATCHPOINT)) { |
|
476 |
addWatchpoint(context, attributes, drm); |
|
477 |
} |
|
478 |
else { |
|
479 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); |
|
480 |
drm.done(); |
|
481 |
} |
|
482 |
} |
|
483 |
||
484 |
/** |
|
485 |
* @param map |
|
486 |
* @param key |
|
487 |
* @param defaultValue |
|
488 |
* @return |
|
489 |
*/ |
|
490 |
public Object getProperty(Map<String, Object> map, String key, Object defaultValue) { |
|
491 |
return (map.containsKey(key) && (map.get(key) != null)) ? map.get(key) : defaultValue; |
|
492 |
} |
|
493 |
||
494 |
/** |
|
495 |
* @param attributes |
|
496 |
* @return |
|
497 |
*/ |
|
498 |
private String formatLocation(Map<String, Object> attributes) { |
|
499 |
||
500 |
// Unlikely default location |
|
501 |
String location = (String) getProperty(attributes, ADDRESS, NULL_STRING); |
|
502 |
||
503 |
// Get the relevant parameters |
|
504 |
String fileName = (String) getProperty(attributes, FILE_NAME, NULL_STRING); |
|
505 |
Integer lineNumber = (Integer) getProperty(attributes, LINE_NUMBER, -1); |
|
506 |
String function = (String) getProperty(attributes, FUNCTION, NULL_STRING); |
|
507 |
||
508 |
// Fix for Bug264721 |
|
509 |
if (fileName.contains(" ")) { //$NON-NLS-1$ |
|
510 |
fileName = "\"" + fileName + "\""; //$NON-NLS-1$//$NON-NLS-2$ |
|
511 |
} |
|
512 |
||
513 |
if (!fileName.equals(NULL_STRING)) { |
|
514 |
if (lineNumber != -1) { |
|
515 |
location = fileName + ":" + lineNumber; //$NON-NLS-1$ |
|
516 |
} else { |
|
517 |
location = fileName + ":" + function; //$NON-NLS-1$ |
|
518 |
} |
|
519 |
} else if (!function.equals(NULL_STRING)) { |
|
520 |
// function location without source |
|
521 |
location = function; |
|
522 |
} else if (location.length() > 0) { |
|
523 |
// address location |
|
524 |
if (Character.isDigit(location.charAt(0))) { |
|
525 |
// numeric address needs '*' prefix |
|
526 |
location = '*' + location; |
|
527 |
} |
|
528 |
} |
|
529 |
||
530 |
return location; |
|
531 |
} |
|
532 |
||
533 |
/** |
|
534 |
* Add a breakpoint of type BREAKPOINT |
|
535 |
* |
|
536 |
* @param context |
|
537 |
* @param breakpoint |
|
538 |
* @param drm |
|
539 |
*/ |
|
540 |
private void addBreakpoint(final IBreakpointsTargetDMContext context, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> drm) |
|
541 |
{ |
|
542 |
// Select the context breakpoints map |
|
543 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
544 |
if (contextBreakpoints == null) { |
|
545 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
546 |
drm.done(); |
|
547 |
return; |
|
548 |
} |
|
549 |
||
550 |
// Extract the relevant parameters (providing default values to avoid potential NPEs) |
|
551 |
String location = formatLocation(attributes); |
|
552 |
if (location.equals(NULL_STRING)) { |
|
553 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
554 |
drm.done(); |
|
555 |
return; |
|
556 |
} |
|
557 |
||
558 |
Boolean isTemporary = (Boolean) getProperty(attributes, MIBreakpointDMData.IS_TEMPORARY, false); |
|
559 |
Boolean isHardware = (Boolean) getProperty(attributes, MIBreakpointDMData.IS_HARDWARE, false); |
|
560 |
final String condition = (String) getProperty(attributes, CONDITION, NULL_STRING); |
|
561 |
Integer ignoreCount = (Integer) getProperty(attributes, IGNORE_COUNT, 0 ); |
|
562 |
String threadId = (String) getProperty(attributes, MIBreakpointDMData.THREAD_ID, "0"); //$NON-NLS-1$ |
|
563 |
int tid = Integer.parseInt(threadId); |
|
564 |
||
565 |
// The DataRequestMonitor for the add request |
|
566 |
DataRequestMonitor<MIBreakInsertInfo> addBreakpointDRM = |
|
567 |
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), drm) { |
|
568 |
@Override |
|
569 |
protected void handleSuccess() { |
|
570 |
||
571 |
// With MI, an invalid location won't generate an error |
|
572 |
if (getData().getMIBreakpoints().length == 0) { |
|
573 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); |
|
574 |
drm.done(); |
|
575 |
return; |
|
576 |
} |
|
577 |
||
578 |
// Create a breakpoint object and store it in the map |
|
579 |
final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); |
|
580 |
int reference = newBreakpoint.getNumber(); |
|
581 |
if (reference == -1) { |
|
582 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); |
|
583 |
drm.done(); |
|
584 |
return; |
|
585 |
} |
|
586 |
contextBreakpoints.put(reference, newBreakpoint); |
|
587 |
||
588 |
// Format the return value |
|
589 |
MIBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); |
|
590 |
drm.setData(dmc); |
|
591 |
||
592 |
// Flag the event |
|
593 |
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); |
|
594 |
||
595 |
// By default the breakpoint is enabled at creation |
|
596 |
// If it wasn't supposed to be, then disable it right away |
|
597 |
Map<String,Object> delta = new HashMap<String,Object>(); |
|
598 |
delta.put(IS_ENABLED, getProperty(attributes, IS_ENABLED, true)); |
|
599 |
modifyBreakpoint(dmc, delta, drm, false); |
|
600 |
} |
|
601 |
||
602 |
@Override |
|
603 |
protected void handleError() { |
|
604 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, BREAKPOINT_INSERTION_FAILURE, null)); |
|
605 |
drm.done(); |
|
606 |
} |
|
607 |
}; |
|
608 |
||
609 |
// Execute the command |
|
610 |
fConnection.queueCommand( |
|
611 |
new MIBreakInsert(context, isTemporary, isHardware, condition, ignoreCount, location, tid), addBreakpointDRM); |
|
612 |
} |
|
613 |
||
614 |
/** |
|
615 |
* Add a breakpoint of type WATCHPOINT |
|
616 |
* |
|
617 |
* @param context |
|
618 |
* @param watchpoint |
|
619 |
* @param drm |
|
620 |
*/ |
|
621 |
private void addWatchpoint(final IBreakpointsTargetDMContext context, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> drm) |
|
622 |
{ |
|
623 |
// Pick the context breakpoints map |
|
624 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
625 |
if (contextBreakpoints == null) { |
|
626 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
627 |
drm.done(); |
|
628 |
return; |
|
629 |
} |
|
630 |
||
631 |
// Extract the relevant parameters (providing default values to avoid potential NPEs) |
|
632 |
String expression = (String) getProperty(attributes, EXPRESSION, NULL_STRING); |
|
633 |
boolean isRead = (Boolean) getProperty(attributes, READ, false); |
|
634 |
boolean isWrite = (Boolean) getProperty(attributes, WRITE, false); |
|
635 |
||
636 |
// The DataRequestMonitor for the add request |
|
637 |
DataRequestMonitor<MIBreakInsertInfo> addWatchpointDRM = |
|
638 |
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), drm) { |
|
639 |
@Override |
|
640 |
protected void handleSuccess() { |
|
641 |
||
642 |
// With MI, an invalid location won't generate an error |
|
643 |
if (getData().getMIBreakpoints().length == 0) { |
|
644 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); |
|
645 |
drm.done(); |
|
646 |
return; |
|
647 |
} |
|
648 |
||
649 |
// Create a breakpoint object and store it in the map |
|
650 |
final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); |
|
651 |
int reference = newBreakpoint.getNumber(); |
|
652 |
if (reference == -1) { |
|
653 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); |
|
654 |
drm.done(); |
|
655 |
return; |
|
656 |
} |
|
657 |
contextBreakpoints.put(reference, newBreakpoint); |
|
658 |
||
659 |
// Format the return value |
|
660 |
IBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { context }, reference); |
|
661 |
drm.setData(dmc); |
|
662 |
||
663 |
// Flag the event |
|
664 |
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); |
|
665 |
||
666 |
// Condition, ignore count and state can not be specified at watchpoint creation time. |
|
667 |
// Therefore, we have to update the watchpoint if any of these is present |
|
668 |
Map<String,Object> delta = new HashMap<String,Object>(); |
|
669 |
delta.put(CONDITION, getProperty(attributes, CONDITION, NULL_STRING)); |
|
670 |
delta.put(IGNORE_COUNT, getProperty(attributes, IGNORE_COUNT, 0 )); |
|
671 |
delta.put(IS_ENABLED, getProperty(attributes, IS_ENABLED, true)); |
|
672 |
modifyBreakpoint(dmc, delta, drm, false); |
|
673 |
} |
|
674 |
||
675 |
@Override |
|
676 |
protected void handleError() { |
|
677 |
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, WATCHPOINT_INSERTION_FAILURE, null)); |
|
678 |
drm.done(); |
|
679 |
} |
|
680 |
}; |
|
681 |
||
682 |
// Execute the command |
|
683 |
fConnection.queueCommand(new MIBreakWatch(context, isRead, isWrite, expression), addWatchpointDRM); |
|
684 |
} |
|
685 |
||
686 |
//------------------------------------------------------------------------- |
|
687 |
// removeBreakpoint |
|
688 |
//------------------------------------------------------------------------- |
|
689 |
||
690 |
/* (non-Javadoc) |
|
691 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints#removeBreakpoint(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext, org.eclipse.cdt.dsf.concurrent.RequestMonitor) |
|
692 |
*/ |
|
693 |
public void removeBreakpoint(final IBreakpointDMContext dmc, final RequestMonitor rm) { |
|
694 |
||
695 |
// Validate the breakpoint context |
|
696 |
if (dmc == null) { |
|
697 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
698 |
rm.done(); |
|
699 |
return; |
|
700 |
} |
|
701 |
||
702 |
// Validate the breakpoint type |
|
703 |
MIBreakpointDMContext breakpointCtx; |
|
704 |
if (dmc instanceof MIBreakpointDMContext) { |
|
705 |
breakpointCtx = (MIBreakpointDMContext) dmc; |
|
706 |
} |
|
707 |
else { |
|
708 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); |
|
709 |
rm.done(); |
|
710 |
return; |
|
711 |
} |
|
712 |
||
713 |
// Validate the target context |
|
714 |
IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); |
|
715 |
if (context == null) { |
|
716 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); |
|
717 |
rm.done(); |
|
718 |
return; |
|
719 |
} |
|
720 |
||
721 |
// Pick the context breakpoints map |
|
722 |
final Map<Integer,MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
723 |
if (contextBreakpoints == null) { |
|
724 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
725 |
rm.done(); |
|
726 |
return; |
|
727 |
} |
|
728 |
||
729 |
// Validate the breakpoint |
|
730 |
final int reference = breakpointCtx.getReference(); |
|
731 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
732 |
if (breakpoint == null) { |
|
733 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
734 |
rm.done(); |
|
735 |
return; |
|
736 |
} |
|
737 |
||
738 |
// Queue the command |
|
739 |
fConnection.queueCommand( |
|
740 |
new MIBreakDelete(context, new int[] { reference }), |
|
741 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
742 |
@Override |
|
743 |
protected void handleCompleted() { |
|
744 |
if (isSuccess()) { |
|
745 |
getSession().dispatchEvent(new BreakpointRemovedEvent(dmc), getProperties()); |
|
746 |
contextBreakpoints.remove(reference); |
|
747 |
} |
|
748 |
rm.done(); |
|
749 |
} |
|
750 |
}); |
|
751 |
} |
|
752 |
||
753 |
// ------------------------------------------------------------------------- |
|
754 |
// updateBreakpoint |
|
755 |
//------------------------------------------------------------------------- |
|
756 |
||
757 |
/* (non-Javadoc) |
|
758 |
* @see org.eclipse.cdt.dsf.debug.service.IBreakpoints#updateBreakpoint(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext, java.util.Map, org.eclipse.cdt.dsf.concurrent.RequestMonitor) |
|
759 |
*/ |
|
760 |
public void updateBreakpoint(IBreakpointDMContext dmc, Map<String, Object> properties, RequestMonitor rm) |
|
761 |
{ |
|
762 |
// Validate the breakpoint context |
|
763 |
if (dmc == null) { |
|
764 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
765 |
rm.done(); |
|
766 |
return; |
|
767 |
} |
|
768 |
||
769 |
// Validate the breakpoint type |
|
770 |
MIBreakpointDMContext breakpointCtx; |
|
771 |
if (dmc instanceof MIBreakpointDMContext) { |
|
772 |
breakpointCtx = (MIBreakpointDMContext) dmc; |
|
773 |
} |
|
774 |
else { |
|
775 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); |
|
776 |
rm.done(); |
|
777 |
return; |
|
778 |
} |
|
779 |
||
780 |
// Validate the context |
|
781 |
IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); |
|
782 |
if (context == null) { |
|
783 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, null)); |
|
784 |
rm.done(); |
|
785 |
return; |
|
786 |
} |
|
787 |
||
788 |
// Pick the context breakpoints map |
|
789 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
790 |
if (contextBreakpoints == null) { |
|
791 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
792 |
rm.done(); |
|
793 |
return; |
|
794 |
} |
|
795 |
||
796 |
// Validate the breakpoint |
|
797 |
final int reference = breakpointCtx.getReference(); |
|
798 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
799 |
if (breakpoint == null) { |
|
800 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
801 |
rm.done(); |
|
802 |
return; |
|
803 |
} |
|
804 |
||
805 |
modifyBreakpoint(dmc, properties, rm, true); |
|
806 |
} |
|
807 |
||
808 |
/** |
|
809 |
* @param dmc |
|
810 |
* @param properties |
|
811 |
* @param rm |
|
812 |
* @param generateUpdateEvent |
|
813 |
*/ |
|
814 |
private void modifyBreakpoint(final IBreakpointDMContext dmc, Map<String, Object> attributes, final RequestMonitor rm, final boolean generateUpdateEvent) |
|
815 |
{ |
|
816 |
// Use a working copy of the attributes since we are going to tamper happily with them |
|
817 |
Map<String, Object> properties = new HashMap<String, Object>(attributes); |
|
818 |
||
819 |
// Retrieve the breakpoint parameters |
|
820 |
// At this point, we know their are OK so there is no need to re-validate |
|
821 |
MIBreakpointDMContext breakpointCtx = (MIBreakpointDMContext) dmc; |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
822 |
final IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); |
37 | 823 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
824 |
final int reference = breakpointCtx.getReference(); |
|
825 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
826 |
||
827 |
// Track the number of change requests |
|
828 |
int numberOfChanges = 0; |
|
829 |
final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { |
|
830 |
@Override |
|
831 |
protected void handleSuccess() { |
|
832 |
if (generateUpdateEvent) |
|
833 |
getSession().dispatchEvent(new BreakpointUpdatedEvent(dmc), getProperties()); |
|
834 |
rm.done(); |
|
835 |
} |
|
836 |
}; |
|
837 |
||
838 |
// Determine if the breakpoint condition changed |
|
839 |
String conditionAttribute = CONDITION; |
|
840 |
if (properties.containsKey(conditionAttribute)) { |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
841 |
final String oldValue = breakpoint.getCondition(); |
37 | 842 |
String newValue = (String) properties.get(conditionAttribute); |
843 |
if (newValue == null) newValue = NULL_STRING; |
|
844 |
if (!oldValue.equals(newValue)) { |
|
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
845 |
changeCondition(context, reference, newValue, new RequestMonitor(getExecutor(), countingRm){ |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
846 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
847 |
@Override |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
848 |
protected void handleError() { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
849 |
// Failed to change the condition, restore the old condition. |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
850 |
// See comment in changeCondition() for more. |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
851 |
MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
852 |
final ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(context, dmc); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
853 |
rollbackCondition(cdtBP, oldValue); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
854 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
855 |
countingRm.done(); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
856 |
}}); |
37 | 857 |
numberOfChanges++; |
858 |
} |
|
859 |
properties.remove(conditionAttribute); |
|
860 |
} |
|
861 |
||
862 |
// Determine if the breakpoint ignore count changed |
|
863 |
String ignoreCountAttribute = IGNORE_COUNT; |
|
864 |
if (properties.containsKey(ignoreCountAttribute)) { |
|
865 |
Integer oldValue = breakpoint.getIgnoreCount(); |
|
866 |
Integer newValue = (Integer) properties.get(ignoreCountAttribute); |
|
867 |
if (newValue == null) newValue = 0; |
|
868 |
if (!oldValue.equals(newValue)) { |
|
869 |
changeIgnoreCount(context, reference, newValue, countingRm); |
|
870 |
numberOfChanges++; |
|
871 |
} |
|
872 |
properties.remove(ignoreCountAttribute); |
|
873 |
} |
|
874 |
||
875 |
// Determine if the breakpoint state changed |
|
876 |
String enableAttribute = IS_ENABLED; |
|
877 |
if (properties.containsKey(enableAttribute)) { |
|
878 |
Boolean oldValue = breakpoint.isEnabled(); |
|
879 |
Boolean newValue = (Boolean) properties.get(enableAttribute); |
|
880 |
if (newValue == null) newValue = false; |
|
881 |
if (!oldValue.equals(newValue)) { |
|
882 |
numberOfChanges++; |
|
883 |
if (newValue) |
|
884 |
enableBreakpoint(context, reference, countingRm); |
|
885 |
else |
|
886 |
disableBreakpoint(context, reference, countingRm); |
|
887 |
} |
|
888 |
properties.remove(enableAttribute); |
|
889 |
} |
|
890 |
||
891 |
// Set the number of completions required |
|
892 |
countingRm.setDoneCount(numberOfChanges); |
|
893 |
} |
|
894 |
||
117
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
895 |
private void rollbackCondition(final ICBreakpoint cdtBP, final String oldValue) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
896 |
if (cdtBP == null) |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
897 |
return; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
898 |
|
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
899 |
new Job("rollback breakpont condition") { //$NON-NLS-1$ |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
900 |
{ setSystem(true); } |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
901 |
@Override |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
902 |
protected IStatus run(IProgressMonitor monitor) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
903 |
try { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
904 |
if (oldValue != null) |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
905 |
cdtBP.setCondition(oldValue); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
906 |
else |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
907 |
cdtBP.setCondition(NULL_STRING); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
908 |
} catch (CoreException e) { |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
909 |
// ignore |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
910 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
911 |
return Status.OK_STATUS; |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
912 |
}}.schedule(); |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
913 |
} |
09f3d307f081
Overhauled BreakpointsMediator to support both EDC and GDB properly. See Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
l12wang
parents:
37
diff
changeset
|
914 |
|
37 | 915 |
/** |
916 |
* Update the breakpoint condition |
|
917 |
* |
|
918 |
* @param context |
|
919 |
* @param dmc |
|
920 |
* @param condition |
|
921 |
* @param rm |
|
922 |
*/ |
|
923 |
private void changeCondition(final IBreakpointsTargetDMContext context, |
|
924 |
final int reference, final String condition, final RequestMonitor rm) |
|
925 |
{ |
|
926 |
// Pick the context breakpoints map |
|
927 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
928 |
if (contextBreakpoints == null) { |
|
929 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
930 |
rm.done(); |
|
931 |
return; |
|
932 |
} |
|
933 |
||
934 |
// Queue the command |
|
935 |
fConnection.queueCommand( |
|
936 |
new MIBreakCondition(context, reference, condition), |
|
937 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
938 |
@Override |
|
939 |
protected void handleSuccess() { |
|
940 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
941 |
if (breakpoint == null) { |
|
942 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
943 |
rm.done(); |
|
944 |
return; |
|
945 |
} |
|
946 |
breakpoint.setCondition(condition); |
|
947 |
rm.done(); |
|
948 |
} |
|
949 |
||
950 |
// In case of error (new condition could not be installed for whatever reason), |
|
951 |
// GDB "offers" different behaviours depending on its version: it can either keep |
|
952 |
// the original condition (the right thing to do) or keep the invalid condition. |
|
953 |
// Our sole option is to remove the condition in case of error and rely on the |
|
954 |
// upper layer to re-install the right condition. |
|
955 |
@Override |
|
956 |
protected void handleError() { |
|
957 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
958 |
if (breakpoint == null) { |
|
959 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
960 |
rm.done(); |
|
961 |
return; |
|
962 |
} |
|
963 |
// Remove invalid condition from the back-end breakpoint |
|
964 |
breakpoint.setCondition(NULL_STRING); |
|
965 |
fConnection.queueCommand( |
|
966 |
new MIBreakCondition(context, reference, NULL_STRING), |
|
967 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
968 |
@Override |
|
969 |
// The report the initial problem |
|
970 |
protected void handleCompleted() { |
|
971 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_CONDITION, null)); |
|
972 |
rm.done(); |
|
973 |
} |
|
974 |
}); |
|
975 |
} |
|
976 |
}); |
|
977 |
} |
|
978 |
||
979 |
||
980 |
/** |
|
981 |
* Update the breakpoint ignoreCount |
|
982 |
* |
|
983 |
* @param context |
|
984 |
* @param reference |
|
985 |
* @param ignoreCount |
|
986 |
* @param rm |
|
987 |
*/ |
|
988 |
private void changeIgnoreCount(IBreakpointsTargetDMContext context, |
|
989 |
final int reference, final int ignoreCount, final RequestMonitor rm) |
|
990 |
{ |
|
991 |
// Pick the context breakpoints map |
|
992 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
993 |
if (contextBreakpoints == null) { |
|
994 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
995 |
rm.done(); |
|
996 |
return; |
|
997 |
} |
|
998 |
||
999 |
// Queue the command |
|
1000 |
fConnection.queueCommand( |
|
1001 |
new MIBreakAfter(context, reference, ignoreCount), |
|
1002 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
1003 |
@Override |
|
1004 |
protected void handleSuccess() { |
|
1005 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
1006 |
if (breakpoint == null) { |
|
1007 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
1008 |
rm.done(); |
|
1009 |
return; |
|
1010 |
} |
|
1011 |
breakpoint.setIgnoreCount(ignoreCount); |
|
1012 |
rm.done(); |
|
1013 |
} |
|
1014 |
}); |
|
1015 |
} |
|
1016 |
||
1017 |
/** |
|
1018 |
* Enable the breakpoint |
|
1019 |
* |
|
1020 |
* @param context |
|
1021 |
* @param reference |
|
1022 |
* @param rm |
|
1023 |
*/ |
|
1024 |
private void enableBreakpoint(IBreakpointsTargetDMContext context, |
|
1025 |
final int reference, final RequestMonitor rm) |
|
1026 |
{ |
|
1027 |
// Pick the context breakpoints map |
|
1028 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
1029 |
if (contextBreakpoints == null) { |
|
1030 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
1031 |
rm.done(); |
|
1032 |
return; |
|
1033 |
} |
|
1034 |
||
1035 |
// Queue the command |
|
1036 |
fConnection.queueCommand( |
|
1037 |
new MIBreakEnable(context, new int[] { reference }), |
|
1038 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
1039 |
@Override |
|
1040 |
protected void handleSuccess() { |
|
1041 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
1042 |
if (breakpoint == null) { |
|
1043 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
1044 |
rm.done(); |
|
1045 |
return; |
|
1046 |
} |
|
1047 |
breakpoint.setEnabled(true); |
|
1048 |
rm.done(); |
|
1049 |
} |
|
1050 |
}); |
|
1051 |
} |
|
1052 |
||
1053 |
/** |
|
1054 |
* Disable the breakpoint |
|
1055 |
* |
|
1056 |
* @param context |
|
1057 |
* @param dmc |
|
1058 |
* @param rm |
|
1059 |
*/ |
|
1060 |
private void disableBreakpoint(IBreakpointsTargetDMContext context, |
|
1061 |
final int reference, final RequestMonitor rm) |
|
1062 |
{ |
|
1063 |
// Pick the context breakpoints map |
|
1064 |
final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context); |
|
1065 |
if (contextBreakpoints == null) { |
|
1066 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); |
|
1067 |
rm.done(); |
|
1068 |
return; |
|
1069 |
} |
|
1070 |
||
1071 |
// Queue the command |
|
1072 |
fConnection.queueCommand( |
|
1073 |
new MIBreakDisable(context, new int[] { reference }), |
|
1074 |
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { |
|
1075 |
@Override |
|
1076 |
protected void handleSuccess() { |
|
1077 |
MIBreakpointDMData breakpoint = contextBreakpoints.get(reference); |
|
1078 |
if (breakpoint == null) { |
|
1079 |
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null)); |
|
1080 |
rm.done(); |
|
1081 |
return; |
|
1082 |
} |
|
1083 |
breakpoint.setEnabled(false); |
|
1084 |
rm.done(); |
|
1085 |
} |
|
1086 |
}); |
|
1087 |
} |
|
1088 |
||
1089 |
} |