1
/*******************************************************************************
2
* Copyright (c) 2000, 2010 QNX Software Systems and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* QNX Software Systems - Initial API and implementation
10
* Anton Leherbauer (Wind River Systems)
11
*******************************************************************************/
12
package org.eclipse.cdt.debug.mi.core.cdi;
15
import java.math.BigInteger;
16
import java.util.ArrayList;
17
import java.util.Arrays;
18
import java.util.Collections;
19
import java.util.HashMap;
20
import java.util.List;
23
import org.eclipse.cdt.debug.core.cdi.CDIException;
24
import org.eclipse.cdt.debug.core.cdi.ICDIAddressLocation;
25
import org.eclipse.cdt.debug.core.cdi.ICDICondition;
26
import org.eclipse.cdt.debug.core.cdi.ICDIFunctionLocation;
27
import org.eclipse.cdt.debug.core.cdi.ICDILineLocation;
28
import org.eclipse.cdt.debug.core.cdi.ICDILocator;
29
import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressBreakpoint;
30
import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint;
31
import org.eclipse.cdt.debug.core.cdi.model.ICDIEventBreakpoint;
32
import org.eclipse.cdt.debug.core.cdi.model.ICDIExceptionpoint;
33
import org.eclipse.cdt.debug.core.cdi.model.ICDIFunctionBreakpoint;
34
import org.eclipse.cdt.debug.core.cdi.model.ICDILineBreakpoint;
35
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
36
import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint;
37
import org.eclipse.cdt.debug.core.model.ICBreakpointType;
38
import org.eclipse.cdt.debug.mi.core.MIException;
39
import org.eclipse.cdt.debug.mi.core.MIFormat;
40
import org.eclipse.cdt.debug.mi.core.MIPlugin;
41
import org.eclipse.cdt.debug.mi.core.MISession;
42
import org.eclipse.cdt.debug.mi.core.cdi.model.AddressBreakpoint;
43
import org.eclipse.cdt.debug.mi.core.cdi.model.AddressLocation;
44
import org.eclipse.cdt.debug.mi.core.cdi.model.Breakpoint;
45
import org.eclipse.cdt.debug.mi.core.cdi.model.EventBreakpoint;
46
import org.eclipse.cdt.debug.mi.core.cdi.model.Exceptionpoint;
47
import org.eclipse.cdt.debug.mi.core.cdi.model.FunctionBreakpoint;
48
import org.eclipse.cdt.debug.mi.core.cdi.model.FunctionLocation;
49
import org.eclipse.cdt.debug.mi.core.cdi.model.LineBreakpoint;
50
import org.eclipse.cdt.debug.mi.core.cdi.model.LocationBreakpoint;
51
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
52
import org.eclipse.cdt.debug.mi.core.cdi.model.Watchpoint;
53
import org.eclipse.cdt.debug.mi.core.command.CLICatch;
54
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
55
import org.eclipse.cdt.debug.mi.core.command.MIBreakAfter;
56
import org.eclipse.cdt.debug.mi.core.command.MIBreakCondition;
57
import org.eclipse.cdt.debug.mi.core.command.MIBreakDelete;
58
import org.eclipse.cdt.debug.mi.core.command.MIBreakDisable;
59
import org.eclipse.cdt.debug.mi.core.command.MIBreakEnable;
60
import org.eclipse.cdt.debug.mi.core.command.MIBreakInsert;
61
import org.eclipse.cdt.debug.mi.core.command.MIBreakList;
62
import org.eclipse.cdt.debug.mi.core.command.MIBreakWatch;
63
import org.eclipse.cdt.debug.mi.core.command.MIGDBSetBreakpointPending;
64
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointChangedEvent;
65
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointCreatedEvent;
66
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointDeletedEvent;
67
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
68
import org.eclipse.cdt.debug.mi.core.output.CLICatchInfo;
69
import org.eclipse.cdt.debug.mi.core.output.MIBreakInsertInfo;
70
import org.eclipse.cdt.debug.mi.core.output.MIBreakListInfo;
71
import org.eclipse.cdt.debug.mi.core.output.MIBreakWatchInfo;
72
import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint;
73
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
76
* Breakpoint Manager for the CDI interface.
78
public class BreakpointManager extends Manager {
80
public static ICDIBreakpoint[] EMPTY_BREAKPOINTS = {};
84
boolean allowInterrupt;
86
public BreakpointManager(Session session) {
87
super(session, false);
88
breakMap = Collections.synchronizedMap(new HashMap());
89
deferredMap = Collections.synchronizedMap(new HashMap());
90
allowInterrupt = true;
93
synchronized List getBreakpointsList(ICDITarget target) {
94
List bList = (List)breakMap.get(target);
96
bList = Collections.synchronizedList(new ArrayList());
97
breakMap.put(target, bList);
102
MIBreakpoint[] getAllMIBreakpoints(MISession miSession) throws CDIException {
103
CommandFactory factory = miSession.getCommandFactory();
104
MIBreakList breakpointList = factory.createMIBreakList();
106
miSession.postCommand(breakpointList);
107
MIBreakListInfo info = breakpointList.getMIBreakListInfo();
109
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
111
return info.getMIBreakpoints();
112
} catch (MIException e) {
113
throw new MI2CDIException(e);
117
boolean hasBreakpointChanged(MIBreakpoint miBreak, MIBreakpoint miBreakpoint) {
118
return miBreak.isEnabled() != miBreakpoint.isEnabled() ||
119
!miBreak.getCondition().equals(miBreakpoint.getCondition()) ||
120
miBreak.getIgnoreCount() != miBreakpoint.getIgnoreCount();
123
public Watchpoint getWatchpoint(MISession miSession, int number) {
124
return (Watchpoint)getBreakpoint(miSession, number);
127
public Breakpoint getBreakpoint(MISession miSession, int number) {
128
Session session = (Session)getSession();
129
Target target = session.getTarget(miSession);
130
if (target != null) {
131
return getBreakpoint(target, number);
136
public Breakpoint getBreakpoint(Target target, int number) {
137
List bList = (List)breakMap.get(target);
139
Breakpoint[] bkpts = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
140
for (int i = 0; i < bkpts.length; i++) {
141
MIBreakpoint[] miBreakpoints = bkpts[i].getMIBreakpoints();
142
for (int j = 0; j < miBreakpoints.length; j++) {
143
if (miBreakpoints[j].getNumber() == number) {
152
boolean suspendInferior(Target target) throws CDIException {
153
boolean shouldRestart = false;
155
if (allowInterrupt && target.isRunning()) {
157
((EventManager) getSession().getEventManager()).allowProcessingEvents(false);
159
shouldRestart = true;
161
return shouldRestart;
164
void resumeInferior(Target target, boolean shouldRestart) throws CDIException {
165
((EventManager) getSession().getEventManager()).allowProcessingEvents(true);
171
public void deleteBreakpoint(MISession miSession, int no) {
172
Session session = (Session)getSession();
173
Target target = session.getTarget(miSession);
174
if (target != null) {
175
deleteBreakpoint(target, no);
180
* Use in the event classes, the breakpoint is not remove from the list
181
* It is only done in DestroyedEvent class. Since we need to keep the breakpoint
186
void deleteBreakpoint (Target target, int no) {
187
List bList = (List)breakMap.get(target);
189
Breakpoint[] points = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
190
for (int i = 0; i < points.length; i++) {
191
MIBreakpoint[] miBreakpoints = points[i].getMIBreakpoints();
192
for (int j = 0; j < miBreakpoints.length; j++) {
193
if (miBreakpoints[j].getNumber() == no) {
194
bList.remove(points[i]);
203
* Call through the Breakpoint class Breakpoint.setEnabled(boolean)
206
* @throws CDIException
208
public void enableBreakpoint(Breakpoint breakpoint) throws CDIException {
209
Target target = (Target)breakpoint.getTarget();
211
// Check if the breakpoint is in the deffered list
212
List dList = (List)deferredMap.get(target);
214
if (dList.contains(breakpoint)) {
215
breakpoint.setEnabled0(true);
216
return; // bail out here, our work is done.
220
List bList = (List)breakMap.get(target);
222
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
224
if (!bList.contains(breakpoint)) {
225
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
227
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
228
if (miBreakpoints == null || miBreakpoints.length == 0) {
229
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
232
int[] numbers = new int[miBreakpoints.length];
233
for (int i = 0; i < miBreakpoints.length; i++) {
234
numbers[i] = miBreakpoints[i].getNumber();
237
boolean restart = false;
238
MISession miSession = target.getMISession();
239
CommandFactory factory = miSession.getCommandFactory();
240
MIBreakEnable breakEnable = factory.createMIBreakEnable(numbers);
242
restart = suspendInferior(target);
243
miSession.postCommand(breakEnable);
244
MIInfo info = breakEnable.getMIInfo();
246
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
248
for (int i = 0; i < miBreakpoints.length; i++) {
249
miBreakpoints[i].setEnabled(true);
251
breakpoint.setEnabled0(true);
252
} catch (MIException e) {
253
throw new MI2CDIException(e);
256
// Resume the program and enable events.
257
resumeInferior(target, restart);
259
// Fire a changed Event.
260
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, numbers[0]));
268
* Call through the Breakpoint class. Breakpoint.disable
271
* @throws CDIException
273
public void disableBreakpoint(Breakpoint breakpoint) throws CDIException {
274
Target target = (Target)breakpoint.getTarget();
276
// Check if the breakpoint is in the deffered list
277
List dList = (List)deferredMap.get(target);
279
if (dList.contains(breakpoint)) {
280
breakpoint.setEnabled0(false);
281
return; // bail out here, our work is done.
285
List bList = (List)breakMap.get(target);
287
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
289
if (!bList.contains(breakpoint)) {
290
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
293
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
294
if (miBreakpoints == null || miBreakpoints.length == 0) {
295
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
297
int[] numbers = new int[miBreakpoints.length];
298
for (int i = 0; i < miBreakpoints.length; i++) {
299
numbers[i] = miBreakpoints[i].getNumber();
302
boolean restart = false;
303
MISession miSession = target.getMISession();
304
CommandFactory factory = miSession.getCommandFactory();
305
MIBreakDisable breakDisable = factory.createMIBreakDisable(numbers);
307
restart = suspendInferior(target);
308
miSession.postCommand(breakDisable);
309
MIInfo info = breakDisable.getMIInfo();
311
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
313
for (int i = 0; i < miBreakpoints.length; i++) {
314
miBreakpoints[i].setEnabled(false);
316
breakpoint.setEnabled0(false);
317
} catch (MIException e) {
318
throw new MI2CDIException(e);
321
resumeInferior(target, restart);
323
// Fire a changed Event.
324
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, numbers[0]));
330
* Use by the Breakpoint class, Breakpoint.setCondition(Condition cond)
331
* In this case we will not try to change the condition with -break-condition.
332
* Since condition may contains new thread-id it is simpler to remove the breakpoints
333
* and make a new breakpoints with the new conditions.
335
* @param newCondition
336
* @throws CDIException
338
public void setCondition(Breakpoint breakpoint, ICDICondition newCondition) throws CDIException {
339
Target target = (Target)breakpoint.getTarget();
341
// Check if the breakpoint is in the deffered list
342
List dList = (List)deferredMap.get(target);
344
if (dList.contains(breakpoint)) {
345
breakpoint.setCondition0(newCondition);
346
return; // bail out here, our work is done.
350
List bList = (List)breakMap.get(target);
352
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
354
if (!bList.contains(breakpoint)) {
355
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
358
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
359
deleteMIBreakpoints(target, miBreakpoints);
360
ICDICondition oldCondition = breakpoint.getCondition();
361
boolean success = false;
363
breakpoint.setCondition0(newCondition);
364
if (breakpoint instanceof LocationBreakpoint) {
365
setLocationBreakpoint((LocationBreakpoint)breakpoint);
366
} else if (breakpoint instanceof Watchpoint) {
367
setWatchpoint((Watchpoint)breakpoint, false);
369
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
374
breakpoint.setCondition0(oldCondition);
375
if (breakpoint instanceof LocationBreakpoint) {
376
setLocationBreakpoint((LocationBreakpoint)breakpoint);
377
} else if (breakpoint instanceof Watchpoint) {
378
setWatchpoint((Watchpoint)breakpoint, false);
383
// Fire a changed Event.
384
miBreakpoints = breakpoint.getMIBreakpoints();
385
if (miBreakpoints != null && miBreakpoints.length > 0) {
386
MISession miSession = target.getMISession();
387
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, miBreakpoints[0].getNumber()));
391
public void update(Target target) throws CDIException {
392
update(target, null);
396
* Pass the event that causes this update
397
* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=135250
399
public void update(Target target, MIEvent event) throws CDIException {
400
MISession miSession = target.getMISession();
401
MIBreakpoint[] allMIBreakpoints = getAllMIBreakpoints(miSession);
402
List bList = getBreakpointsList(target);
403
List eventList = new ArrayList(allMIBreakpoints.length);
404
for (int i = 0; i < allMIBreakpoints.length; i++) {
405
MIBreakpoint miBreakpoint = allMIBreakpoints[i];
406
int no = miBreakpoint.getNumber();
407
Breakpoint bp = getBreakpoint(target, no);
409
MIBreakpoint[] miBps = bp.getMIBreakpoints();
410
for (int j = 0; j < miBps.length; j++) {
411
if (miBps[j].getNumber() == no) {
412
if (hasBreakpointChanged(miBps[j], miBreakpoint)) {
413
miBps[j] = miBreakpoint;
414
bp.setEnabled0(miBreakpoint.isEnabled());
415
// FIXME: We have a problem if the thread id change.
416
ICDICondition oldCond = bp.getCondition();
417
String[] tids = oldCond.getThreadIds();
418
Condition newCondition = new Condition(miBreakpoint.getIgnoreCount(),
419
miBreakpoint.getCondition(), tids);
420
bp.setCondition0(newCondition);
422
eventList.add(new MIBreakpointChangedEvent(miSession, no));
427
// add the new breakpoint and fire CreatedEvent
428
int type = ICBreakpointType.REGULAR;
429
if (miBreakpoint.isHardware()) {
430
type = ICBreakpointType.HARDWARE;
431
} else if (miBreakpoint.isTemporary()) {
432
type = ICBreakpointType.TEMPORARY;
434
String[] tids = null;
435
String tid = miBreakpoint.getThreadId();
436
if (tid != null && tid.length() > 0) {
437
tids = new String[] { tid };
439
Condition condition = new Condition(miBreakpoint.getIgnoreCount(),
440
miBreakpoint.getCondition(), tids);
442
if (miBreakpoint.isWatchpoint()) {
444
if (miBreakpoint.isAccessWatchpoint() || miBreakpoint.isReadWatchpoint()) {
445
watchType |= ICDIWatchpoint.READ;
447
if (miBreakpoint.isAccessWatchpoint() || miBreakpoint.isWriteWatchpoint()) {
448
watchType |= ICDIWatchpoint.WRITE;
450
Watchpoint wpoint = new Watchpoint(target, miBreakpoint.getWhat(), type, watchType, condition, miBreakpoint.isEnabled());
451
wpoint.setMIBreakpoints(new MIBreakpoint[] {miBreakpoint});
454
int hint = MIBreakpointChangedEvent.HINT_NONE;
455
if (event instanceof MIBreakpointChangedEvent) {
456
hint = ((MIBreakpointChangedEvent)event).getHint();
458
String function = miBreakpoint.getFunction();
459
String file = miBreakpoint.getFile();
460
int line = miBreakpoint.getLine();
461
String addr = miBreakpoint.getAddress();
462
boolean enabled = miBreakpoint.isEnabled();
464
Breakpoint newBreakpoint = null;
465
if (hint == MIBreakpointChangedEvent.HINT_NEW_LINE_BREAKPOINT ||
466
(hint == MIBreakpointChangedEvent.HINT_NONE && file != null && file.length() > 0 && line > 0)) {
467
LineLocation location = createLineLocation (miBreakpoint.getFile(),
468
miBreakpoint.getLine());
469
newBreakpoint = new LineBreakpoint(target, type, location, condition, enabled);
470
} else if ((hint == MIBreakpointChangedEvent.HINT_NEW_FUNCTION_BREAKPOINT ||
471
hint == MIBreakpointChangedEvent.HINT_NONE) && function != null && function.length() > 0) {
472
FunctionLocation location = createFunctionLocation(file, function);
473
newBreakpoint = new FunctionBreakpoint(target, type, location, condition, enabled);
474
} else if (hint == MIBreakpointChangedEvent.HINT_NEW_EVENTBREAKPOINT || EventBreakpoint.getEventTypeFromMI(miBreakpoint)!=null) {
475
String ctype = EventBreakpoint.getEventTypeFromMI(miBreakpoint);
477
newBreakpoint = new EventBreakpoint(target, ctype, EventBreakpoint
478
.getEventArgumentFromMI(miBreakpoint), condition, enabled);
480
MIPlugin.log("Unsupported event breakpoint: "+miBreakpoint.getWhat()); //$NON-NLS-1$ log entry not for users
482
} else if (addr != null && addr.length() > 0) {
483
BigInteger big = MIFormat.getBigInteger(addr);
484
AddressLocation location = createAddressLocation(big);
485
newBreakpoint = new AddressBreakpoint(target, type, location, condition,
488
if (newBreakpoint != null) {
489
newBreakpoint.setMIBreakpoints(new MIBreakpoint[] { miBreakpoint });
490
bList.add(newBreakpoint);
493
eventList.add(new MIBreakpointCreatedEvent(miSession, no));
496
// Check if any breakpoint was removed.
497
Breakpoint[] oldBreakpoints = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
498
for (int i = 0; i < oldBreakpoints.length; i++) {
499
boolean found = false;
500
MIBreakpoint[] miBreakpoints = oldBreakpoints[i].getMIBreakpoints();
501
for (int j = 0; j < miBreakpoints.length; j++) {
502
int no = miBreakpoints[j].getNumber();
503
for (int k = 0; k < allMIBreakpoints.length; k++) {
504
if (no == allMIBreakpoints[k].getNumber()) {
510
// Fire destroyed Events.
511
eventList.add(new MIBreakpointDeletedEvent(miSession, no));
515
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
516
miSession.fireEvents(events);
520
* @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#allowProgramInterruption()
522
public void allowProgramInterruption(boolean e) {
526
public void deleteFromDeferredList(Breakpoint bkpt) {
527
List dList = (List)deferredMap.get(bkpt.getTarget());
534
* Use by the EventManager when checking for deferred breapoints.
537
public void addToBreakpointList(Breakpoint bkpt) {
538
List bList = getBreakpointsList(bkpt.getTarget());
542
public void deleteAllBreakpoints(Target target) throws CDIException {
543
List bList = (List)breakMap.get(target);
545
ICDIBreakpoint[] bps = new ICDIBreakpoint[bList.size()];
547
deleteBreakpoints(target, bps);
551
* @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#deleteBreakpoint(ICDIBreakpoint)
553
public void deleteBreakpoint(ICDIBreakpoint breakpoint) throws CDIException {
554
deleteBreakpoints((Target)breakpoint.getTarget(), new ICDIBreakpoint[] { breakpoint });
557
public void deleteBreakpoints(Target target, ICDIBreakpoint[] breakpoints) throws CDIException {
558
List bList = (List)breakMap.get(target);
559
List dList = (List)deferredMap.get(target);
561
// Do the sanity check first, we will accept all or none
563
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
565
for (int i = 0; i < breakpoints.length; i++) {
566
if (!(breakpoints[i] instanceof Breakpoint && (bList.contains(breakpoints[i]) || (dList != null && dList.contains(breakpoints[i]))))) {
567
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
571
MISession miSession = target.getMISession();
572
List eventList = new ArrayList(breakpoints.length);
573
for (int i = 0; i < breakpoints.length; i++) {
574
if (!(dList != null && dList.remove(breakpoints[i]))) {
575
MIBreakpoint[] miBreakpoints = ((Breakpoint)breakpoints[i]).getMIBreakpoints();
576
if (miBreakpoints.length > 0) {
577
deleteMIBreakpoints(target, miBreakpoints);
578
eventList.add(new MIBreakpointDeletedEvent(miSession, miBreakpoints[0].getNumber()));
582
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
583
miSession.fireEvents(events);
586
void deleteMIBreakpoints(Target target, MIBreakpoint[] miBreakpoints) throws CDIException {
587
MISession miSession = target.getMISession();
588
int[] numbers = new int[miBreakpoints.length];
589
for (int i = 0; i < miBreakpoints.length; ++i) {
590
numbers[i] = miBreakpoints[i].getNumber();
592
boolean restart = false;
594
restart = suspendInferior(target);
595
deleteMIBreakpoints(miSession, numbers);
597
resumeInferior(target, restart);
601
void deleteMIBreakpoints(MISession miSession, int[] numbers) throws CDIException {
602
CommandFactory factory = miSession.getCommandFactory();
603
MIBreakDelete breakDelete = factory.createMIBreakDelete(numbers);
605
miSession.postCommand(breakDelete);
606
MIInfo info = breakDelete.getMIInfo();
608
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
610
} catch (MIException e) {
611
throw new MI2CDIException(e);
615
public ICDIBreakpoint[] getBreakpoints(Target target) throws CDIException {
616
List list = (List)breakMap.get(target);
618
ICDIBreakpoint[] bps = new ICDIBreakpoint[list.size()];
622
return EMPTY_BREAKPOINTS;
625
public ICDIBreakpoint[] getDeferredBreakpoints(Target target) throws CDIException {
626
List dlist = (List)deferredMap.get(target);
628
ICDIBreakpoint[] bps = new ICDIBreakpoint[dlist.size()];
632
return EMPTY_BREAKPOINTS;
636
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement#setLineBreakpoint(int, org.eclipse.cdt.debug.core.cdi.ICDILineLocation, org.eclipse.cdt.debug.core.cdi.ICDICondition, boolean)
638
public ICDILineBreakpoint setLineBreakpoint(Target target, int type, ICDILineLocation location,
639
ICDICondition condition, boolean deferred, boolean enabled) throws CDIException {
640
LineBreakpoint bkpt = new LineBreakpoint(target, type, location, condition, enabled);
641
setNewLocationBreakpoint(bkpt, deferred);
646
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement#setFunctionBreakpoint(int, org.eclipse.cdt.debug.core.cdi.ICDIFunctionLocation, org.eclipse.cdt.debug.core.cdi.ICDICondition, boolean)
648
public ICDIFunctionBreakpoint setFunctionBreakpoint(Target target, int type, ICDIFunctionLocation location,
649
ICDICondition condition, boolean deferred, boolean enabled) throws CDIException {
650
FunctionBreakpoint bkpt = new FunctionBreakpoint(target, type, location, condition, enabled);
651
setNewLocationBreakpoint(bkpt, deferred);
656
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement#setAddressBreakpoint(int, org.eclipse.cdt.debug.core.cdi.ICDIAddressLocation, org.eclipse.cdt.debug.core.cdi.ICDICondition, boolean)
658
public ICDIAddressBreakpoint setAddressBreakpoint(Target target, int type, ICDIAddressLocation location,
659
ICDICondition condition, boolean deferred, boolean enabled) throws CDIException {
660
AddressBreakpoint bkpt = new AddressBreakpoint(target, type, location, condition, enabled);
661
setNewLocationBreakpoint(bkpt, deferred);
666
protected void setNewLocationBreakpoint(LocationBreakpoint bkpt, boolean deferred) throws CDIException {
667
Target target = (Target)bkpt.getTarget();
668
MISession miSession = target.getMISession();
670
setLocationBreakpoint(bkpt);
671
List blist = getBreakpointsList(target);
674
// Fire a created Event.
675
MIBreakpoint[] miBreakpoints = bkpt.getMIBreakpoints();
676
if (miBreakpoints != null && miBreakpoints.length > 0) {
677
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
679
} catch (CDIException e) {
683
Session session = (Session)target.getSession();
684
SharedLibraryManager sharedMgr = session.getSharedLibraryManager();
685
if (sharedMgr.isDeferredBreakpoint(target)) {
686
addDeferredBreakpoint(bkpt);
693
private void addDeferredBreakpoint(Breakpoint breakpoint) {
694
Target target = (Target)breakpoint.getTarget();
695
List dList = (List)deferredMap.get(target);
697
dList = Collections.synchronizedList(new ArrayList());
698
deferredMap.put(target, dList);
700
dList.add(breakpoint);
703
public void setLocationBreakpoint (LocationBreakpoint bkpt) throws CDIException {
704
Target target = (Target)bkpt.getTarget();
705
MISession miSession = target.getMISession();
706
MIBreakInsert[] breakInserts = createMIBreakInsert(bkpt, miSession.isBreakpointsWithFullName());
707
List pointList = new ArrayList();
708
boolean restart = false;
710
restart = suspendInferior(target);
711
CommandFactory factory = miSession.getCommandFactory();
712
boolean enable = bkpt.isEnabled();
713
for (int i = 0; i < breakInserts.length; i++) {
714
miSession.postCommand(breakInserts[i]);
715
MIBreakInsertInfo info = breakInserts[i].getMIBreakInsertInfo();
717
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
719
MIBreakpoint[] points = info.getMIBreakpoints();
720
if (points == null || points.length == 0) {
721
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$
724
if (bkpt.getFile() != null && bkpt.getFile().length() > 0)
726
for (int j = 0; j < points.length; j++) {
727
points[j].setFile(bkpt.getFile());
730
if (bkpt.getLineNumber()>0) {
731
for (int j = 0; j < points.length; j++) {
732
if (points[j].getLine() == 0)
733
points[j].setLine(bkpt.getLineNumber());
736
// Make sure that if the breakpoint was disable we create them disable.
738
int[] numbers = new int[points.length];
739
for (int j = 0; j < points.length; j++) {
740
numbers[j] = points[j].getNumber();
742
MIBreakDisable breakDisable = factory.createMIBreakDisable(numbers);
744
miSession.postCommand(breakDisable);
745
MIInfo disableInfo = breakDisable.getMIInfo();
746
if (disableInfo == null) {
747
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
749
} catch (MIException e) {
750
throw new MI2CDIException(e);
754
pointList.addAll(Arrays.asList(points));
756
} catch (MIException e) {
758
// Things did not go well remove all the breakpoints we've set before.
759
MIBreakpoint[] allPoints = (MIBreakpoint[]) pointList.toArray(new MIBreakpoint[pointList.size()]);
760
if (allPoints != null && allPoints.length > 0) {
761
deleteMIBreakpoints(target, allPoints);
763
} catch (CDIException cdie) {
766
throw new MI2CDIException(e);
768
resumeInferior(target, restart);
770
MIBreakpoint[] allPoints = (MIBreakpoint[]) pointList.toArray(new MIBreakpoint[pointList.size()]);
771
bkpt.setMIBreakpoints(allPoints);
774
public void setWatchpoint(Watchpoint bkpt) throws CDIException {
775
setWatchpoint(bkpt, true);
778
private void setWatchpoint(Watchpoint watchpoint, boolean isNew) throws CDIException {
779
Target target = (Target)watchpoint.getTarget();
780
boolean access = watchpoint.isReadType() && watchpoint.isWriteType();
781
boolean read = ! watchpoint.isWriteType() && watchpoint.isReadType();
782
String expression = watchpoint.getDerivedExpression();
783
boolean enable = watchpoint.isEnabled();
785
MISession miSession = target.getMISession();
786
CommandFactory factory = miSession.getCommandFactory();
787
MIBreakWatch breakWatch =
788
factory.createMIBreakWatch(access, read, expression);
789
MIBreakpoint[] points = null;
790
boolean restart = false;
792
restart = suspendInferior(target);
793
miSession.postCommand(breakWatch);
794
MIBreakWatchInfo winfo = breakWatch.getMIBreakWatchInfo();
796
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
798
points = winfo.getMIBreakpoints();
799
if (points == null || points.length == 0) {
800
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$
803
int no = points[0].getNumber();
805
// Put the condition now.
806
String exprCond = null;
809
ICDICondition condition = watchpoint.getCondition();
810
if (condition != null) {
811
exprCond = condition.getExpression();
812
ignoreCount = condition.getIgnoreCount();
814
if (exprCond != null && exprCond.length() > 0) {
815
MIBreakCondition breakCondition = factory.createMIBreakCondition(no, exprCond);
816
miSession.postCommand(breakCondition);
817
MIInfo info = breakCondition.getMIInfo();
819
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
822
if (ignoreCount > 0) {
823
MIBreakAfter breakAfter = factory.createMIBreakAfter(no, ignoreCount);
824
miSession.postCommand(breakAfter);
825
MIInfo info = breakAfter.getMIInfo();
827
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
831
int[] numbers = new int[1];
833
MIBreakDisable breakDisable = factory.createMIBreakDisable(numbers);
835
miSession.postCommand(breakDisable);
836
MIInfo disableInfo = breakDisable.getMIInfo();
837
if (disableInfo == null) {
838
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
840
} catch (MIException e) {
841
throw new MI2CDIException(e);
844
// how to deal with threads ???
845
} catch (MIException e) {
846
throw new MI2CDIException(e);
848
resumeInferior(target, restart);
850
watchpoint.setMIBreakpoints(points);
853
List bList = getBreakpointsList(target);
854
bList.add(watchpoint);
856
// Fire a created Event.
857
MIBreakpoint[] miBreakpoints = watchpoint.getMIBreakpoints();
858
if (miBreakpoints != null && miBreakpoints.length > 0) {
859
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
864
Breakpoint[] exceptionBps = new Breakpoint[2];
865
final int EXCEPTION_THROW_IDX = 0;
866
final int EXCEPTION_CATCH_IDX = 1;
867
final static String[] EXCEPTION_FUNCS = new String[] {"__cxa_throw", "__cxa_begin_catch"}; //$NON-NLS-1$ //$NON-NLS-2$
870
public ICDIExceptionpoint setExceptionpoint(Target target, String clazz, boolean stopOnThrow,
871
boolean stopOnCatch, boolean enabled) throws CDIException {
873
if (!stopOnThrow && !stopOnCatch) {
874
throw new CDIException("Must suspend on throw or catch"); //$NON-NLS-1$
877
MIBreakpoint[] miBreakpoints = null;
880
synchronized(exceptionBps) {
881
int id = EXCEPTION_THROW_IDX;
882
if (exceptionBps[EXCEPTION_THROW_IDX] == null) {
883
FunctionLocation location = new FunctionLocation(null, EXCEPTION_FUNCS[id]);
884
FunctionBreakpoint bp = new FunctionBreakpoint(target, ICBreakpointType.REGULAR, location, null, enabled);
885
setLocationBreakpoint(bp);
886
exceptionBps[id] = bp;
887
miBreakpoints = bp.getMIBreakpoints();
892
synchronized(exceptionBps) {
893
int id = EXCEPTION_THROW_IDX;
894
if (exceptionBps[id] == null) {
895
FunctionLocation location = new FunctionLocation(null, EXCEPTION_FUNCS[id]);
896
FunctionBreakpoint bp = new FunctionBreakpoint(target, ICBreakpointType.REGULAR, location, null, enabled);
897
setLocationBreakpoint(bp);
898
exceptionBps[id] = bp;
899
if (miBreakpoints != null) {
900
MIBreakpoint[] mibp = bp.getMIBreakpoints();
901
MIBreakpoint[] temp = new MIBreakpoint[miBreakpoints.length + mibp.length];
902
System.arraycopy(miBreakpoints, 0, temp, 0, miBreakpoints.length);
903
System.arraycopy(mibp, 0, temp, miBreakpoints.length, mibp.length);
905
miBreakpoints = bp.getMIBreakpoints();
911
Exceptionpoint excp = new Exceptionpoint(target, clazz, stopOnThrow, stopOnCatch, null, enabled);
912
if (miBreakpoints != null && miBreakpoints.length > 0) {
913
excp.setMIBreakpoints(miBreakpoints);
914
List blist = getBreakpointsList(target);
917
// Fire a created Event.
918
MISession miSession = target.getMISession();
919
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
925
* Call -gdb-set breakpoint pending set
928
* @throws CDIException
930
public void setBreakpointPending(Target target, boolean set) throws CDIException {
931
MISession miSession = target.getMISession();
932
CommandFactory factory = miSession.getCommandFactory();
933
MIGDBSetBreakpointPending bpp = factory.createMIGDBSetBreakpointPending(set);
935
miSession.postCommand(bpp);
936
MIInfo info = bpp.getMIInfo();
938
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
940
} catch (MIException e) {
941
throw new MI2CDIException(e);
945
public Condition createCondition(int ignoreCount, String expression, String[] tids) {
946
return new Condition(ignoreCount, expression, tids);
949
public LineLocation createLineLocation(String file, int line) {
950
return new LineLocation(file, line);
953
public FunctionLocation createFunctionLocation(String file, String function) {
954
return new FunctionLocation(file, function);
957
public AddressLocation createAddressLocation(BigInteger address) {
958
return new AddressLocation(address);
960
MIBreakInsert[] createMIBreakInsert(LocationBreakpoint bkpt) throws CDIException {
961
return createMIBreakInsert(bkpt, false);
963
MIBreakInsert[] createMIBreakInsert(LocationBreakpoint bkpt, boolean fullPath) throws CDIException {
964
boolean hardware = bkpt.isHardware();
965
boolean temporary = bkpt.isTemporary();
966
String exprCond = null;
968
String[] threadIds = null;
969
StringBuffer line = new StringBuffer();
971
if (bkpt.getCondition() != null) {
972
ICDICondition condition = bkpt.getCondition();
973
exprCond = condition.getExpression();
974
ignoreCount = condition.getIgnoreCount();
975
threadIds = condition.getThreadIds();
978
if (bkpt.getLocator() != null) {
979
ICDILocator locator = bkpt.getLocator();
980
String file = locator.getFile();
982
if (fullPath==false) {
983
file = new File(file).getName();
986
String function = locator.getFunction();
987
int no = locator.getLineNumber();
988
if (bkpt instanceof LineBreakpoint) {
989
if (file != null && file.length() > 0) {
990
line.append(file).append(':');
993
} else if (bkpt instanceof FunctionBreakpoint) {
994
if (function != null && function.length() > 0) {
995
// if the function contains :: assume the user
996
// knows the exact funciton
997
int colon = function.indexOf("::"); //$NON-NLS-1$
999
line.append(function);
1001
if (file != null && file.length() > 0) {
1002
line.append(file).append(':');
1004
// GDB does not seem to accept function arguments when
1005
// we use file name:
1006
// (gdb) break file.c:Test(int)
1007
// Will fail, altought it can accept this
1008
// (gdb) break file.c:main
1009
// so fall back to the line number or
1010
// just the name of the function if lineno is invalid.
1011
int paren = function.indexOf('(');
1014
String func = function.substring(0, paren);
1020
line.append(function);
1025
if (file != null && file.length() > 0) {
1026
line.append(file).append(':');
1032
} else if (bkpt instanceof AddressBreakpoint) {
1033
line.append('*').append(locator.getAddress());
1036
if (file != null && file.length() > 0) {
1037
line.append(file).append(':');
1043
MIBreakInsert[] miBreakInserts;
1044
MISession miSession = ((Target)bkpt.getTarget()).getMISession();
1045
CommandFactory factory = miSession.getCommandFactory();
1046
if (threadIds == null || threadIds.length == 0) {
1047
MIBreakInsert bi = factory.createMIBreakInsert(temporary, hardware, exprCond, ignoreCount, line.toString(), 0);
1048
miBreakInserts = new MIBreakInsert[] { bi } ;
1050
List list = new ArrayList(threadIds.length);
1051
for (int i = 0; i < threadIds.length; i++) {
1052
String threadId = threadIds[i];
1054
if (threadId != null && threadId.length() > 0) {
1056
tid = Integer.parseInt(threadId);
1057
list.add(factory.createMIBreakInsert(temporary, hardware, exprCond, ignoreCount, line.toString(), tid));
1058
} catch (NumberFormatException e) {
1062
miBreakInserts = (MIBreakInsert[]) list.toArray(new MIBreakInsert[list.size()]);
1064
return miBreakInserts;
1066
public ICDIEventBreakpoint setEventBreakpoint(Target target, String type, String arg, ICDICondition condition, boolean enabled) throws CDIException {
1067
EventBreakpoint eventBkpt = new EventBreakpoint(target,type,arg,condition,enabled);
1068
setEventBreakpoint(eventBkpt);
1071
public void setEventBreakpoint(EventBreakpoint eventBkpt) throws CDIException {
1072
Target target = (Target) eventBkpt.getTarget();
1074
MISession miSession = target.getMISession();
1075
CommandFactory factory = miSession.getCommandFactory();
1076
CLICatch breakCatch = factory.createCLICatch(eventBkpt.getGdbEvent(), eventBkpt
1079
eventBkpt.setMIBreakpoints(new MIBreakpoint[0]); // initialize
1080
boolean restart = false;
1082
restart = suspendInferior(target);
1083
miSession.postCommand(breakCatch);
1086
CLICatchInfo cinfo = (CLICatchInfo) breakCatch.getMIInfo();
1087
if (cinfo == null) {
1088
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
1090
MIBreakpoint[] points = cinfo.getMIBreakpoints();
1091
if (points == null || points.length == 0) {
1092
throw new CDIException(CdiResources
1093
.getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$
1095
no = points[0].getNumber();
1096
eventBkpt.setMIBreakpoints(points);
1097
} catch (MIException e) {
1098
if (!eventBkpt.isDeferred()) {
1101
addDeferredBreakpoint(eventBkpt);
1105
// Put the condition now.
1106
String exprCond = null;
1107
int ignoreCount = 0;
1109
ICDICondition condition = eventBkpt.getCondition();
1110
if (condition != null) {
1111
exprCond = condition.getExpression();
1112
ignoreCount = condition.getIgnoreCount();
1114
if (exprCond != null && exprCond.length() > 0) {
1115
MIBreakCondition breakCondition = factory.createMIBreakCondition(no, exprCond);
1116
miSession.postCommand(breakCondition);
1117
MIInfo info = breakCondition.getMIInfo();
1119
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
1122
if (ignoreCount > 0) {
1123
MIBreakAfter breakAfter = factory.createMIBreakAfter(no, ignoreCount);
1124
miSession.postCommand(breakAfter);
1125
MIInfo info = breakAfter.getMIInfo();
1127
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
1130
// how to deal with threads ???
1131
} catch (MIException e) {
1132
throw new MI2CDIException(e);
1134
resumeInferior(target, restart);
1139
List bList = getBreakpointsList(target);
1140
bList.add(eventBkpt);
1142
// Fire a created Event.
1143
MIBreakpoint[] miBreakpoints = eventBkpt.getMIBreakpoints();
1144
if (miBreakpoints != null && miBreakpoints.length > 0) {
1145
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0]