blob: 57d3fbdba1ce4cb431555a44901a9f0757aace58 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core.cdi;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDICondition;
import org.eclipse.cdt.debug.core.cdi.ICDILocation;
import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint;
import org.eclipse.cdt.debug.core.cdi.model.ICDIExceptionpoint;
import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint;
import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MIFormat;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.cdi.model.Breakpoint;
import org.eclipse.cdt.debug.mi.core.cdi.model.Exceptionpoint;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.cdi.model.Watchpoint;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIBreakAfter;
import org.eclipse.cdt.debug.mi.core.command.MIBreakCondition;
import org.eclipse.cdt.debug.mi.core.command.MIBreakDelete;
import org.eclipse.cdt.debug.mi.core.command.MIBreakDisable;
import org.eclipse.cdt.debug.mi.core.command.MIBreakEnable;
import org.eclipse.cdt.debug.mi.core.command.MIBreakInsert;
import org.eclipse.cdt.debug.mi.core.command.MIBreakList;
import org.eclipse.cdt.debug.mi.core.command.MIBreakWatch;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointChangedEvent;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointCreatedEvent;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointDeletedEvent;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.output.MIBreakInsertInfo;
import org.eclipse.cdt.debug.mi.core.output.MIBreakListInfo;
import org.eclipse.cdt.debug.mi.core.output.MIBreakWatchInfo;
import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
/**
* Breakpoint Manager for the CDI interface.
*/
public class BreakpointManager extends Manager {
public static ICDIBreakpoint[] EMPTY_BREAKPOINTS = {};
Map breakMap;
Map deferredMap;
boolean allowInterrupt;
public BreakpointManager(Session session) {
super(session, false);
breakMap = Collections.synchronizedMap(new HashMap());
deferredMap = Collections.synchronizedMap(new HashMap());
allowInterrupt = true;
}
synchronized List getBreakpointsList(Target target) {
List bList = (List)breakMap.get(target);
if (bList == null) {
bList = Collections.synchronizedList(new ArrayList());
breakMap.put(target, bList);
}
return bList;
}
MIBreakpoint[] getAllMIBreakpoints(MISession miSession) throws CDIException {
CommandFactory factory = miSession.getCommandFactory();
MIBreakList breakpointList = factory.createMIBreakList();
try {
miSession.postCommand(breakpointList);
MIBreakListInfo info = breakpointList.getMIBreakListInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
return info.getMIBreakpoints();
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
boolean hasBreakpointChanged(MIBreakpoint miBreak, MIBreakpoint miBreakpoint) {
return miBreak.isEnabled() != miBreakpoint.isEnabled() ||
!miBreak.getCondition().equals(miBreakpoint.getCondition()) ||
miBreak.getIgnoreCount() != miBreakpoint.getIgnoreCount();
}
public Watchpoint getWatchpoint(MISession miSession, int number) {
return (Watchpoint)getBreakpoint(miSession, number);
}
public Breakpoint getBreakpoint(MISession miSession, int number) {
Session session = (Session)getSession();
Target target = session.getTarget(miSession);
if (target != null) {
return getBreakpoint(target, number);
}
return null;
}
public Breakpoint getBreakpoint(Target target, int number) {
List bList = (List)breakMap.get(target);
if (bList != null) {
Breakpoint[] bkpts = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
for (int i = 0; i < bkpts.length; i++) {
MIBreakpoint[] miBreakpoints = bkpts[i].getMIBreakpoints();
for (int j = 0; j < miBreakpoints.length; j++) {
if (miBreakpoints[j].getNumber() == number) {
return bkpts[i];
}
}
}
}
return null;
}
boolean suspendInferior(Target target) throws CDIException {
boolean shouldRestart = false;
// Stop the program
if (allowInterrupt && target.isRunning()) {
// Disable events.
((EventManager)getSession().getEventManager()).allowProcessingEvents(false);
target.suspend();
shouldRestart = true;
}
return shouldRestart;
}
void resumeInferior(Target target, boolean shouldRestart) throws CDIException {
if (shouldRestart) {
target.resume();
((EventManager)getSession().getEventManager()).allowProcessingEvents(true);
}
}
public void deleteBreakpoint(MISession miSession, int no) {
Session session = (Session)getSession();
Target target = session.getTarget(miSession);
if (target != null) {
deleteBreakpoint(target, no);
}
}
/**
* Use in the event classes, the breakpoint is not remove from the list
* It is only done in DestroyedEvent class. Since we need to keep the breakpoint
* type around.
* @param target
* @param no
*/
void deleteBreakpoint (Target target, int no) {
List bList = (List)breakMap.get(target);
if (bList != null) {
Breakpoint[] points = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
for (int i = 0; i < points.length; i++) {
MIBreakpoint[] miBreakpoints = points[i].getMIBreakpoints();
for (int j = 0; j < miBreakpoints.length; j++) {
if (miBreakpoints[j].getNumber() == no) {
bList.remove(points[i]);
break;
}
}
}
}
}
/**
* Call through the Breakpoint class Breakpoint.setEnabled(boolean)
*
* @param breakpoint
* @throws CDIException
*/
public void enableBreakpoint(Breakpoint breakpoint) throws CDIException {
Target target = (Target)breakpoint.getTarget();
// Check if the breakpoint is in the deffered list
List dList = (List)deferredMap.get(target);
if (dList != null) {
if (dList.contains(breakpoint)) {
breakpoint.setEnabled0(true);
return; // bail out here, our work is done.
}
}
List bList = (List)breakMap.get(target);
if (bList == null) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
if (!bList.contains(breakpoint)) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
if (miBreakpoints == null || miBreakpoints.length == 0) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
int[] numbers = new int[miBreakpoints.length];
for (int i = 0; i < miBreakpoints.length; i++) {
numbers[i] = miBreakpoints[i].getNumber();
}
boolean restart = false;
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
MIBreakEnable breakEnable = factory.createMIBreakEnable(numbers);
try {
restart = suspendInferior(target);
miSession.postCommand(breakEnable);
MIInfo info = breakEnable.getMIInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
// Resume the program and enable events.
resumeInferior(target, restart);
}
for (int i = 0; i < miBreakpoints.length; i++) {
miBreakpoints[i].setEnabled(true);
}
breakpoint.setEnabled0(true);
// Fire a changed Event.
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, numbers[0]));
}
/**
* Call through the Breakpoint class. Breakpoint.disable
*
* @param breakpoint
* @throws CDIException
*/
public void disableBreakpoint(Breakpoint breakpoint) throws CDIException {
Target target = (Target)breakpoint.getTarget();
// Check if the breakpoint is in the deffered list
List dList = (List)deferredMap.get(target);
if (dList != null) {
if (dList.contains(breakpoint)) {
breakpoint.setEnabled0(false);
return; // bail out here, our work is done.
}
}
List bList = (List)breakMap.get(target);
if (bList == null) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
if (!bList.contains(breakpoint)) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
if (miBreakpoints == null || miBreakpoints.length == 0) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
int[] numbers = new int[miBreakpoints.length];
for (int i = 0; i < miBreakpoints.length; i++) {
numbers[i] = miBreakpoints[i].getNumber();
}
boolean restart = false;
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
MIBreakDisable breakDisable = factory.createMIBreakDisable(numbers);
try {
restart = suspendInferior(target);
miSession.postCommand(breakDisable);
MIInfo info = breakDisable.getMIInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
resumeInferior(target, restart);
}
for (int i = 0; i < miBreakpoints.length; i++) {
miBreakpoints[i].setEnabled(false);
}
breakpoint.setEnabled0(false);
// Fire a changed Event.
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, numbers[0]));
}
/**
* Use by the Breakpoint class, Breakpoint.setCondition(Condition cond)
* In this case we will not try to change the condition with -break-condition.
* Since condition may contains new thread-id it is simpler to remove the breakpoints
* and make a new breakpoints with the new conditions.
* @param breakpoint
* @param newCondition
* @throws CDIException
*/
public void setCondition(Breakpoint breakpoint, ICDICondition newCondition) throws CDIException {
Target target = (Target)breakpoint.getTarget();
// Check if the breakpoint is in the deffered list
List dList = (List)deferredMap.get(target);
if (dList != null) {
if (dList.contains(breakpoint)) {
breakpoint.setCondition0(newCondition);
return; // bail out here, our work is done.
}
}
List bList = (List)breakMap.get(target);
if (bList == null) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
if (!bList.contains(breakpoint)) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
MIBreakpoint[] miBreakpoints = breakpoint.getMIBreakpoints();
deleteMIBreakpoints(target, miBreakpoints);
ICDICondition oldCondition = breakpoint.getCondition();
boolean success = false;
try {
breakpoint.setCondition0(newCondition);
if (breakpoint instanceof Watchpoint) {
setWatchpoint((Watchpoint)breakpoint);
} else {
setLocationBreakpoint(breakpoint);
}
success = true;
} finally {
if (!success) {
breakpoint.setCondition0(oldCondition);
if (breakpoint instanceof Watchpoint) {
setWatchpoint((Watchpoint)breakpoint);
} else {
setLocationBreakpoint(breakpoint);
}
}
}
// Fire a changed Event.
miBreakpoints = breakpoint.getMIBreakpoints();
if (miBreakpoints != null && miBreakpoints.length > 0) {
MISession miSession = target.getMISession();
miSession.fireEvent(new MIBreakpointChangedEvent(miSession, miBreakpoints[0].getNumber()));
}
}
/**
*/
public void update(Target target) throws CDIException {
MISession miSession = target.getMISession();
MIBreakpoint[] allMIBreakpoints = getAllMIBreakpoints(miSession);
List bList = getBreakpointsList(target);
List eventList = new ArrayList(allMIBreakpoints.length);
for (int i = 0; i < allMIBreakpoints.length; i++) {
int no = allMIBreakpoints[i].getNumber();
Breakpoint bp = getBreakpoint(target, no);
if (bp != null) {
MIBreakpoint[] miBps = bp.getMIBreakpoints();
for (int j = 0; j < miBps.length; j++) {
if (miBps[j].getNumber() == no) {
if (hasBreakpointChanged(miBps[j], allMIBreakpoints[i])) {
miBps[j] = allMIBreakpoints[i];
bp.setEnabled0(allMIBreakpoints[i].isEnabled());
// FIXME: We have a problem if the thread id change.
ICDICondition oldCond = bp.getCondition();
String[] tids = oldCond.getThreadIds();
Condition newCondition = new Condition(allMIBreakpoints[i].getIgnoreCount(),
allMIBreakpoints[i].getCondition(), tids);
bp.setCondition0(newCondition);
// Fire ChangedEvent
eventList.add(new MIBreakpointChangedEvent(miSession, no));
}
}
}
} else {
// add the new breakpoint and fire CreatedEvent
int type = ICDIBreakpoint.REGULAR;
if (allMIBreakpoints[i].isHardware()) {
type = ICDIBreakpoint.HARDWARE;
} else if (allMIBreakpoints[i].isTemporary()) {
type = ICDIBreakpoint.TEMPORARY;
}
String[] tids = null;
String tid = allMIBreakpoints[i].getThreadId();
if (tid != null && tid.length() > 0) {
tids = new String[] { tid };
}
Condition condition = new Condition(allMIBreakpoints[i].getIgnoreCount(),
allMIBreakpoints[i].getCondition(), tids);
if (allMIBreakpoints[i].isWatchpoint()) {
int watchType = 0;
if (allMIBreakpoints[i].isAccessWatchpoint() || allMIBreakpoints[i].isReadWatchpoint()) {
watchType &= ICDIWatchpoint.READ;
}
if (allMIBreakpoints[i].isAccessWatchpoint() || allMIBreakpoints[i].isWriteWatchpoint()) {
watchType &= ICDIWatchpoint.WRITE;
}
Watchpoint wpoint = new Watchpoint(target, allMIBreakpoints[i].getWhat(), type, watchType, condition);
wpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]});
bList.add(wpoint);
} else {
Location location = new Location (allMIBreakpoints[i].getFile(),
allMIBreakpoints[i].getFunction(),
allMIBreakpoints[i].getLine(),
MIFormat.getBigInteger(allMIBreakpoints[i].getAddress()));
Breakpoint newBreakpoint = new Breakpoint(target, type, location, condition);
newBreakpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]});
bList.add(newBreakpoint);
}
eventList.add(new MIBreakpointCreatedEvent(miSession, no));
}
}
// Check if any breakpoint was removed.
Breakpoint[] oldBreakpoints = (Breakpoint[]) bList.toArray(new Breakpoint[0]);
for (int i = 0; i < oldBreakpoints.length; i++) {
boolean found = false;
MIBreakpoint[] miBreakpoints = oldBreakpoints[i].getMIBreakpoints();
for (int j = 0; j < miBreakpoints.length; j++) {
int no = miBreakpoints[j].getNumber();
for (int k = 0; k < allMIBreakpoints.length; k++) {
if (no == allMIBreakpoints[k].getNumber()) {
found = true;
break;
}
}
if (!found) {
// Fire destroyed Events.
eventList.add(new MIBreakpointDeletedEvent(miSession, no));
}
}
}
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
miSession.fireEvents(events);
}
/**
* @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#allowProgramInterruption()
*/
public void allowProgramInterruption(boolean e) {
allowInterrupt = e;
}
public void deleteFromDeferredList(Breakpoint bkpt) {
List dList = (List)deferredMap.get(bkpt.getTarget());
if (dList != null) {
dList.remove(bkpt);
}
}
/**
* Use by the EventManager when checking for deferred breapoints.
* @param bkpt
*/
public void addToBreakpointList(Breakpoint bkpt) {
List bList = (List)breakMap.get(bkpt.getTarget());
if (bList != null) {
bList.add(bkpt);
}
}
public void deleteAllBreakpoints(Target target) throws CDIException {
List bList = (List)breakMap.get(target);
if (bList != null) {
ICDIBreakpoint[] bps = new ICDIBreakpoint[bList.size()];
bList.toArray(bps);
deleteBreakpoints(target, bps);
}
}
/**
* @see org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager#deleteBreakpoint(ICDIBreakpoint)
*/
public void deleteBreakpoint(ICDIBreakpoint breakpoint) throws CDIException {
deleteBreakpoints((Target)breakpoint.getTarget(), new ICDIBreakpoint[] { breakpoint });
}
public void deleteBreakpoints(Target target, ICDIBreakpoint[] breakpoints) throws CDIException {
List bList = (List)breakMap.get(target);
List dList = (List)deferredMap.get(target);
// Do the sanity check first, we will accept all or none
if (bList == null) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
for (int i = 0; i < breakpoints.length; i++) {
if (!(breakpoints[i] instanceof Breakpoint && (bList.contains(breakpoints[i]) || (dList != null && dList.contains(breakpoints[i]))))) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Not_a_CDT_breakpoint")); //$NON-NLS-1$
}
}
MISession miSession = target.getMISession();
List eventList = new ArrayList(breakpoints.length);
for (int i = 0; i < breakpoints.length; i++) {
if (!(dList != null && dList.remove(breakpoints[i]))) {
MIBreakpoint[] miBreakpoints = ((Breakpoint)breakpoints[i]).getMIBreakpoints();
if (miBreakpoints.length > 0) {
deleteMIBreakpoints(target, miBreakpoints);
eventList.add(new MIBreakpointDeletedEvent(miSession, miBreakpoints[0].getNumber()));
}
}
}
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
miSession.fireEvents(events);
}
void deleteMIBreakpoints(Target target, MIBreakpoint[] miBreakpoints) throws CDIException {
MISession miSession = target.getMISession();
int[] numbers = new int[miBreakpoints.length];
for (int i = 0; i < miBreakpoints.length; ++i) {
numbers[i] = miBreakpoints[i].getNumber();
}
boolean restart = false;
try {
restart = suspendInferior(target);
deleteMIBreakpoints(miSession, numbers);
} finally {
resumeInferior(target, restart);
}
}
void deleteMIBreakpoints(MISession miSession, int[] numbers) throws CDIException {
CommandFactory factory = miSession.getCommandFactory();
MIBreakDelete breakDelete = factory.createMIBreakDelete(numbers);
try {
miSession.postCommand(breakDelete);
MIInfo info = breakDelete.getMIInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
public ICDIBreakpoint[] getBreakpoints(Target target) throws CDIException {
List list = (List)breakMap.get(target);
if (list != null) {
ICDIBreakpoint[] bps = new ICDIBreakpoint[list.size()];
list.toArray(bps);
return bps;
}
return EMPTY_BREAKPOINTS;
}
public ICDIBreakpoint[] getDeferredBreakpoints(Target target) throws CDIException {
List dlist = (List)deferredMap.get(target);
if (dlist != null) {
ICDIBreakpoint[] bps = new ICDIBreakpoint[dlist.size()];
dlist.toArray(bps);
return bps;
}
return EMPTY_BREAKPOINTS;
}
public ICDILocationBreakpoint setLocationBreakpoint(Target target, int type, ICDILocation location,
ICDICondition condition, boolean deferred) throws CDIException {
MISession miSession = target.getMISession();
Breakpoint bkpt = new Breakpoint(target, type, location, condition);
try {
setLocationBreakpoint(bkpt);
List blist = getBreakpointsList(target);
blist.add(bkpt);
// Force the reset of the location.
bkpt.setLocation(null);
// Fire a created Event.
MIBreakpoint[] miBreakpoints = bkpt.getMIBreakpoints();
if (miBreakpoints != null && miBreakpoints.length > 0) {
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
}
} catch (CDIException e) {
if (!deferred) {
throw e;
}
Session session = (Session)target.getSession();
SharedLibraryManager sharedMgr = session.getSharedLibraryManager();
if (sharedMgr.isDeferredBreakpoint()) {
List dList = (List)deferredMap.get(target);
if (dList == null) {
dList = Collections.synchronizedList(new ArrayList());
deferredMap.put(target, dList);
}
dList.add(bkpt);
} else {
throw e;
}
}
return bkpt;
}
MIBreakInsert[] createMIBreakInsert(Breakpoint bkpt) throws CDIException {
boolean hardware = bkpt.isHardware();
boolean temporary = bkpt.isTemporary();
String exprCond = null;
int ignoreCount = 0;
String[] threadIds = null;
StringBuffer line = new StringBuffer();
if (bkpt.getCondition() != null) {
ICDICondition condition = bkpt.getCondition();
exprCond = condition.getExpression();
ignoreCount = condition.getIgnoreCount();
threadIds = condition.getThreadIds();
}
ICDILocation location = bkpt.getLocation();
if (bkpt.isLineBreakpoint()) {
String file = location.getFile();
if (file != null && file.length() > 0) {
line.append(file).append(':');
}
line.append(location.getLineNumber());
} else if (bkpt.isFunctionBreakpoint()) {
String file = location.getFile();
if (file != null && file.length() > 0) {
line.append(file).append(':');
}
String function = location.getFunction();
// GDB does not seem to accept function arguments when
// we use file name:
// (gdb) break file.c:Test(int)
// Will fail, altought it can accept this
// (gdb) break file.c:main
// so fall back to the line number or
// just the name of the function if lineno is invalid.
int paren = function.indexOf('(');
if (paren != -1) {
int no = location.getLineNumber();
if (no <= 0) {
String func = function.substring(0, paren);
line.append(func);
} else {
line.append(no);
}
} else {
line.append(function);
}
} else if (bkpt.isAddressBreakpoint()) {
line.append('*').append(location.getAddress());
}
MIBreakInsert[] miBreakInserts;
MISession miSession = ((Target)bkpt.getTarget()).getMISession();
CommandFactory factory = miSession.getCommandFactory();
if (threadIds == null || threadIds.length == 0) {
MIBreakInsert bi = factory.createMIBreakInsert(temporary, hardware, exprCond, ignoreCount, line.toString(), 0);
miBreakInserts = new MIBreakInsert[] { bi } ;
} else {
List list = new ArrayList(threadIds.length);
for (int i = 0; i < threadIds.length; i++) {
String threadId = threadIds[i];
int tid = 0;
if (threadId != null && threadId.length() > 0) {
try {
tid = Integer.parseInt(threadId);
list.add(factory.createMIBreakInsert(temporary, hardware, exprCond, ignoreCount, line.toString(), tid));
} catch (NumberFormatException e) {
}
}
}
miBreakInserts = (MIBreakInsert[]) list.toArray(new MIBreakInsert[list.size()]);
}
return miBreakInserts;
}
public void setLocationBreakpoint (Breakpoint bkpt) throws CDIException {
Target target = (Target)bkpt.getTarget();
MISession miSession = target.getMISession();
boolean restart = false;
MIBreakInsert[] breakInserts = createMIBreakInsert(bkpt);
List pointList = new ArrayList();
try {
restart = suspendInferior(target);
CommandFactory factory = miSession.getCommandFactory();
boolean enable = bkpt.isEnabled();
for (int i = 0; i < breakInserts.length; i++) {
miSession.postCommand(breakInserts[i]);
MIBreakInsertInfo info = breakInserts[i].getMIBreakInsertInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
MIBreakpoint[] points = info.getMIBreakpoints();
if (points == null || points.length == 0) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$
}
// Make sure that if the breakpoint was disable we create them disable.
if (!enable) {
int[] numbers = new int[points.length];
for (int j = 0; j < points.length; j++) {
numbers[j] = points[j].getNumber();
}
MIBreakDisable breakDisable = factory.createMIBreakDisable(numbers);
try {
miSession.postCommand(breakDisable);
MIInfo disableInfo = breakDisable.getMIInfo();
if (disableInfo == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
pointList.addAll(Arrays.asList(points));
}
} catch (MIException e) {
try {
// Things did not go well remove all the breakpoints we've set before.
MIBreakpoint[] allPoints = (MIBreakpoint[]) pointList.toArray(new MIBreakpoint[pointList.size()]);
if (allPoints != null && allPoints.length > 0) {
deleteMIBreakpoints(target, allPoints);
}
} catch (CDIException cdie) {
// ignore this one;
}
throw new MI2CDIException(e);
} finally {
resumeInferior(target, restart);
}
MIBreakpoint[] allPoints = (MIBreakpoint[]) pointList.toArray(new MIBreakpoint[pointList.size()]);
bkpt.setMIBreakpoints(allPoints);
}
public ICDIWatchpoint setWatchpoint(Target target, int type, int watchType, String expression,
ICDICondition condition) throws CDIException {
try {
// Check if this an address watchpoint, and add a '*'
Integer.decode(expression);
expression = '*' + expression;
} catch (NumberFormatException e) {
//
}
Watchpoint bkpt = new Watchpoint(target, expression, type, watchType, condition);
setWatchpoint(bkpt);
List bList = getBreakpointsList(target);
bList.add(bkpt);
// Fire a created Event.
MIBreakpoint[] miBreakpoints = bkpt.getMIBreakpoints();
if (miBreakpoints != null && miBreakpoints.length > 0) {
MISession miSession = target.getMISession();
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
}
return bkpt;
}
public void setWatchpoint(Watchpoint wp) throws CDIException {
Target target = (Target)wp.getTarget();
boolean access = wp.isReadType() && wp.isWriteType();
boolean read = wp.isReadType() && ! wp.isWriteType();
String expression = wp.getWatchExpression();
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
MIBreakWatch breakWatch =
factory.createMIBreakWatch(access, read, expression);
MIBreakpoint[] points = null;
boolean restart = false;
try {
restart = suspendInferior(target);
miSession.postCommand(breakWatch);
MIBreakWatchInfo winfo = breakWatch.getMIBreakWatchInfo();
points = winfo.getMIBreakpoints();
if (winfo == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
if (points == null || points.length == 0) {
throw new CDIException(CdiResources.getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$
}
int no = points[0].getNumber();
// Put the condition now.
String exprCond = null;
int ignoreCount = 0;
String[] threadIds = null;
StringBuffer line = new StringBuffer();
ICDICondition condition = wp.getCondition();
if (condition != null) {
exprCond = condition.getExpression();
ignoreCount = condition.getIgnoreCount();
threadIds = condition.getThreadIds();
}
if (exprCond != null && exprCond.length() > 0) {
MIBreakCondition breakCondition = factory.createMIBreakCondition(no, exprCond);
miSession.postCommand(breakCondition);
MIInfo info = breakCondition.getMIInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
}
if (ignoreCount > 0) {
MIBreakAfter breakAfter = factory.createMIBreakAfter(no, ignoreCount);
miSession.postCommand(breakAfter);
MIInfo info = breakAfter.getMIInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
}
// how to deal with threads ???
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
resumeInferior(target, restart);
}
wp.setMIBreakpoints(points);
}
Breakpoint[] exceptionBps = new Breakpoint[2];
final int EXCEPTION_THROW_IDX = 0;
final int EXCEPTION_CATCH_IDX = 1;
final static String[] EXCEPTION_FUNCS = new String[] {"__cxa_throw", "__cxa_begin_catch"}; //$NON-NLS-1$ //$NON-NLS-2$
public ICDIExceptionpoint setExceptionpoint(Target target, String clazz, boolean stopOnThrow,
boolean stopOnCatch) throws CDIException {
if (!stopOnThrow && !stopOnCatch) {
throw new CDIException("Must suspend on throw or catch"); //$NON-NLS-1$
}
MIBreakpoint[] miBreakpoints = null;
if (stopOnThrow) {
synchronized(exceptionBps) {
int id = EXCEPTION_THROW_IDX;
if (exceptionBps[EXCEPTION_THROW_IDX] == null) {
Location location = new Location(null, EXCEPTION_FUNCS[id], 0);
Breakpoint bp = new Breakpoint(target, ICDIBreakpoint.REGULAR, location, null);
setLocationBreakpoint(bp);
exceptionBps[id] = bp;
miBreakpoints = bp.getMIBreakpoints();
}
}
}
if (stopOnCatch) {
synchronized(exceptionBps) {
int id = EXCEPTION_THROW_IDX;
if (exceptionBps[id] == null) {
Location location = new Location(null, EXCEPTION_FUNCS[id], 0);
Breakpoint bp = new Breakpoint(target, ICDIBreakpoint.REGULAR, location, null);
setLocationBreakpoint(bp);
exceptionBps[id] = bp;
if (miBreakpoints != null) {
MIBreakpoint[] mibp = bp.getMIBreakpoints();
MIBreakpoint[] temp = new MIBreakpoint[miBreakpoints.length + mibp.length];
System.arraycopy(miBreakpoints, 0, temp, 0, miBreakpoints.length);
System.arraycopy(mibp, 0, temp, miBreakpoints.length, mibp.length);
} else {
miBreakpoints = bp.getMIBreakpoints();
}
}
}
}
Exceptionpoint excp = new Exceptionpoint(target, clazz, stopOnThrow, stopOnCatch);
if (miBreakpoints != null && miBreakpoints.length > 0) {
excp.setMIBreakpoints(miBreakpoints);
List blist = getBreakpointsList(target);
blist.add(excp);
// Fire a created Event.
MISession miSession = target.getMISession();
miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0].getNumber()));
}
return excp;
}
public Condition createCondition(int ignoreCount, String expression, String[] tids) {
return new Condition(ignoreCount, expression, tids);
}
public Location createLocation(String file, String function, int line) {
return new Location(file, function, line);
}
public Location createLocation(BigInteger address) {
return new Location(address);
}
}