blob: 527f9236daaf20603e6ed96347394d7bc1651d41 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, this program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.debug.internal.core.pdi.manager;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.ptp.core.util.BitList;
import org.eclipse.ptp.debug.core.pdi.IPDIAddressLocation;
import org.eclipse.ptp.debug.core.pdi.IPDICondition;
import org.eclipse.ptp.debug.core.pdi.IPDIFunctionLocation;
import org.eclipse.ptp.debug.core.pdi.IPDILineLocation;
import org.eclipse.ptp.debug.core.pdi.IPDISession;
import org.eclipse.ptp.debug.core.pdi.PDIException;
import org.eclipse.ptp.debug.core.pdi.PDILocationFactory;
import org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager;
import org.eclipse.ptp.debug.core.pdi.model.IPDIAddressBreakpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDIExceptionpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDIFunctionBreakpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDILineBreakpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDILocationBreakpoint;
import org.eclipse.ptp.debug.core.pdi.model.IPDIWatchpoint;
import org.eclipse.ptp.debug.core.pdi.request.IPDIEventRequest;
/**
* @author clement
*
*/
public class BreakpointManager extends AbstractPDIManager implements IPDIBreakpointManager {
public static IPDIBreakpoint[] EMPTY_BREAKPOINTS = {};
private final static String[] EXCEPTION_FUNCS = new String[] {"__cxa_throw", "__cxa_begin_catch"};
private List<IPDIBreakpoint> breakList = Collections.synchronizedList(new ArrayList<IPDIBreakpoint>());
private IPDIBreakpoint[] exceptionBps = new IPDIBreakpoint[2];
private final int EXCEPTION_THROW_IDX = 0;
private final int EXCEPTION_CATCH_IDX = 1;
public BreakpointManager(IPDISession session) {
super(session, false);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#addSetBreakpoint(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint)
*/
public void addSetBreakpoint(BitList tasks, IPDIBreakpoint breakpoint) throws PDIException {
if (!isValid(breakpoint.getBreakpointID())) {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
breakpoint.getTasks().or(tasks);
breakpoint.getPendingTasks().or(tasks);
setPendingBreakpoint(breakpoint);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#createAddressLocation(java.math.BigInteger)
*/
public IPDIAddressLocation createAddressLocation(BigInteger address) {
return PDILocationFactory.newAddressLocation(address);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#createCondition(int, java.lang.String, java.lang.String[])
*/
public IPDICondition createCondition(int ignoreCount, String expression, String[] tids) {
return session.getModelFactory().newCondition(ignoreCount, expression, tids);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#createFunctionLocation(java.lang.String, java.lang.String)
*/
public IPDIFunctionLocation createFunctionLocation(String file, String function) {
return PDILocationFactory.newFunctionLocation(file, function);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#createLineLocation(java.lang.String, int)
*/
public IPDILineLocation createLineLocation(String file, int line) {
return PDILocationFactory.newLineLocation(file, line);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#deleteAllBreakpoints()
*/
public void deleteAllBreakpoints() throws PDIException {
IPDIBreakpoint[] pdiBreakpoints = getAllPDIBreakpoints();
for (IPDIBreakpoint pdiBpt : pdiBreakpoints) {
deleteBreakpoint(session.getTasks(), pdiBpt);
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#deleteAllBreakpoints(org.eclipse.ptp.core.util.BitList)
*/
public void deleteAllBreakpoints(BitList tasks) throws PDIException {
IPDIBreakpoint[] pdiBreakpoints = getAllPDIBreakpoints();
for (IPDIBreakpoint pdiBpt : pdiBreakpoints) {
if (pdiBpt.getTasks().intersects(tasks)) {
deleteBreakpoint(tasks, pdiBpt);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#deleteBreakpoint(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint)
*/
public void deleteBreakpoint(BitList tasks, IPDIBreakpoint breakpoint) throws PDIException {
if (!isValid(breakpoint.getBreakpointID())) {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
breakpoint.setDeleted();
deletePendingBreakpoint(breakpoint, true);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#deleteSetBreakpoint(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint)
*/
public void deleteSetBreakpoint(BitList tasks, IPDIBreakpoint breakpoint) throws PDIException {
if (!isValid(breakpoint.getBreakpointID())) {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
breakpoint.getTasks().andNot(tasks);
breakpoint.getPendingTasks().andNot(tasks);
breakpoint.setDeleted();
deletePendingBreakpoint(breakpoint, false);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#disableBreakpoint(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint)
*/
public void disableBreakpoint(BitList tasks, IPDIBreakpoint breakpoint) throws PDIException {
if (!isValid(breakpoint.getBreakpointID())) {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
breakpoint.setEnabled(false);
getSession().getEventRequestManager().addEventRequest(session.getRequestFactory().getDisableBreakpointRequest(tasks, breakpoint));
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#enableBreakpoint(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint)
*/
public void enableBreakpoint(BitList tasks, IPDIBreakpoint breakpoint) throws PDIException {
if (!isValid(breakpoint.getBreakpointID())) {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
breakpoint.setEnabled(true);
getSession().getEventRequestManager().addEventRequest(session.getRequestFactory().getEnableBreakpointRequest(tasks, breakpoint));
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#getBreakpoint(int)
*/
public IPDIBreakpoint getBreakpoint(int id) {
IPDIBreakpoint[] pdiBreakpoints = getAllPDIBreakpoints();
for (IPDIBreakpoint pdiBreakpoint : pdiBreakpoints) {
if (pdiBreakpoint.getBreakpointID() == id) {
return pdiBreakpoint;
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setAddressBreakpoint(org.eclipse.ptp.core.util.BitList, int, org.eclipse.ptp.debug.core.pdi.IPDIAddressLocation, org.eclipse.ptp.debug.core.pdi.IPDICondition, boolean, boolean)
*/
public IPDIAddressBreakpoint setAddressBreakpoint(BitList tasks, int type, IPDIAddressLocation location, IPDICondition condition, boolean deferred, boolean enabled) throws PDIException {
IPDIAddressBreakpoint bkpt = session.getModelFactory().newAddressBreakpoint(session, tasks, type, location, condition, enabled);
setNewLocationBreakpoint(bkpt, deferred);
return bkpt;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setCondition(org.eclipse.ptp.core.util.BitList, org.eclipse.ptp.debug.core.pdi.model.IPDIBreakpoint, org.eclipse.ptp.debug.core.pdi.IPDICondition)
*/
public void setCondition(BitList tasks, IPDIBreakpoint breakpoint, IPDICondition newCondition) throws PDIException {
deleteBreakpoint(tasks, breakpoint);
breakpoint.setCondition(newCondition);
if (breakpoint instanceof IPDILocationBreakpoint) {
setLocationBreakpoint((IPDILocationBreakpoint)breakpoint);
} else if (breakpoint instanceof IPDIWatchpoint) {
setWatchpoint((IPDIWatchpoint)breakpoint);
} else {
throw new PDIException(tasks, PDIResources.getString("pdi.BreakpointManager.Not_a_PTP_breakpoint"));
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setExceptionpoint(org.eclipse.ptp.core.util.BitList, java.lang.String, boolean, boolean, boolean)
*/
public IPDIExceptionpoint setExceptionpoint(BitList tasks, String clazz, boolean stopOnThrow, boolean stopOnCatch, boolean enabled) throws PDIException {
if (!stopOnThrow && !stopOnCatch) {
throw new PDIException(tasks, "Must suspend on throw or catch");
}
List<IPDIFunctionBreakpoint> funcBptList = new ArrayList<IPDIFunctionBreakpoint>(2);
if (stopOnThrow) {
synchronized(exceptionBps) {
int id = EXCEPTION_THROW_IDX;
if (exceptionBps[EXCEPTION_THROW_IDX] == null) {
IPDIFunctionLocation location = PDILocationFactory.newFunctionLocation(null, EXCEPTION_FUNCS[id]);
IPDIFunctionBreakpoint bp = session.getModelFactory().newFunctionBreakpoint(session, tasks, IPDIBreakpoint.REGULAR, location, null, enabled);
setLocationBreakpoint(bp);
exceptionBps[id] = bp;
funcBptList.add(bp);
}
}
}
if (stopOnCatch) {
synchronized(exceptionBps) {
int id = EXCEPTION_THROW_IDX;
if (exceptionBps[id] == null) {
IPDIFunctionLocation location = PDILocationFactory.newFunctionLocation(null, EXCEPTION_FUNCS[id]);
IPDIFunctionBreakpoint bp = session.getModelFactory().newFunctionBreakpoint(session, tasks, IPDIBreakpoint.REGULAR, location, null, enabled);
setLocationBreakpoint(bp);
exceptionBps[id] = bp;
funcBptList.add(bp);
}
}
}
IPDIExceptionpoint excp = session.getModelFactory().newExceptionpoint(session, tasks, clazz, stopOnThrow, stopOnCatch, null, enabled, funcBptList.toArray(new IPDIFunctionBreakpoint[0]));
addBreakpoint(excp);
return excp;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setFunctionBreakpoint(org.eclipse.ptp.core.util.BitList, int, org.eclipse.ptp.debug.core.pdi.IPDIFunctionLocation, org.eclipse.ptp.debug.core.pdi.IPDICondition, boolean, boolean)
*/
public IPDIFunctionBreakpoint setFunctionBreakpoint(BitList tasks, int type, IPDIFunctionLocation location, IPDICondition condition, boolean deferred, boolean enabled) throws PDIException {
IPDIFunctionBreakpoint bkpt = session.getModelFactory().newFunctionBreakpoint(session, tasks, type, location, condition, enabled);
setNewLocationBreakpoint(bkpt, deferred);
return bkpt;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setLineBreakpoint(org.eclipse.ptp.core.util.BitList, int, org.eclipse.ptp.debug.core.pdi.IPDILineLocation, org.eclipse.ptp.debug.core.pdi.IPDICondition, boolean, boolean)
*/
public IPDILineBreakpoint setLineBreakpoint(BitList tasks, int type, IPDILineLocation location, IPDICondition condition, boolean deferred, boolean enabled) throws PDIException {
IPDILineBreakpoint bkpt = session.getModelFactory().newLineBreakpoint(session, tasks, type, location, condition, enabled);
setNewLocationBreakpoint(bkpt, deferred);
return bkpt;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#setWatchpoint(org.eclipse.ptp.core.util.BitList, int, int, java.lang.String, org.eclipse.ptp.debug.core.pdi.IPDICondition, boolean)
*/
public IPDIWatchpoint setWatchpoint(BitList tasks, int type, int watchType, String expression, IPDICondition condition, boolean enabled) throws PDIException {
IPDIWatchpoint bkpt = session.getModelFactory().newWatchpoint(session, tasks, type, expression, watchType, condition, enabled);
setWatchpoint(bkpt);
addBreakpoint(bkpt);
return bkpt;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.internal.core.pdi.AbstractPDIManager#shutdown()
*/
public void shutdown() {
//breakList.clear();
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.internal.core.pdi.AbstractPDIManager#update(org.eclipse.ptp.core.util.BitList)
*/
public void update(BitList tasks) throws PDIException {
//TODO
}
/**
* @param breakpoint
*/
private void addBreakpoint(IPDIBreakpoint breakpoint) {
synchronized(breakList) {
if (!breakpoint.isTemporary()) {
breakList.add(breakpoint);
}
}
}
/**
* @param id
*/
private void deleteBreakpoint(int id) {
IPDIBreakpoint[] pdiBreakpoints = getAllPDIBreakpoints();
for (int i=0; i<pdiBreakpoints.length; i++) {
if (pdiBreakpoints[i].getBreakpointID() == id) {
breakList.remove(i);
break;
}
}
}
/**
* @return
*/
private IPDIBreakpoint[] getAllPDIBreakpoints() {
synchronized(breakList) {
return breakList.toArray(new IPDIBreakpoint[0]);
}
}
/**
* @param id
* @return
*/
private boolean isValid(int id) {
return (getBreakpoint(id) != null);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.manager.IPDIBreakpointManager#updatePendingBreakpoints()
*/
public void updatePendingBreakpoints() throws PDIException {
for (IPDIBreakpoint bp : getAllPDIBreakpoints()) {
if (!bp.getPendingTasks().isEmpty()) {
if (!bp.isDeleted()) {
setPendingBreakpoint(bp);
} else {
deletePendingBreakpoint(bp, true);
}
}
}
}
/**
* Set a breakpoint on all suspended tasks.
*
* @param bp breakpoint to set
* @throws PDIException
*/
public void setPendingBreakpoint(IPDIBreakpoint bp) throws PDIException {
BitList suspendedTasks = bp.getPendingTasks().copy();
if (session.getStatus() == IPDISession.STARTED) {
getSession().getTaskManager().getSuspendedTasks(suspendedTasks);
}
if (!suspendedTasks.isEmpty()) {
IPDIEventRequest request = null;
if (bp instanceof IPDIFunctionBreakpoint) {
request = session.getRequestFactory().getSetFunctionBreakpointRequest(suspendedTasks, (IPDIFunctionBreakpoint)bp, true);
}
else if (bp instanceof IPDIAddressBreakpoint) {
request = session.getRequestFactory().getSetAddressBreakpointRequest(suspendedTasks, (IPDIAddressBreakpoint)bp, true);
}
else if (bp instanceof IPDILineBreakpoint) {
request = session.getRequestFactory().getSetLineBreakpointRequest(suspendedTasks, (IPDILineBreakpoint)bp, true);
}
else if (bp instanceof IPDIWatchpoint) {
request = session.getRequestFactory().getSetWatchpointRequest(suspendedTasks, (IPDIWatchpoint)bp, true);
}
else {
throw new PDIException(bp.getTasks(), PDIResources.getString("pdi.Common.Not_implemented"));
}
bp.getPendingTasks().andNot(suspendedTasks);
getSession().getEventRequestManager().addEventRequest(request);
}
}
/**
* FIXME work out correct usage of allowUpdate
*
* Delete a breakpoint from all suspended tasks.
*
* @param bp breakpoint to delete
* @throws PDIException
*/
public void deletePendingBreakpoint(IPDIBreakpoint bp, boolean allowUpdate) throws PDIException {
BitList suspendedTasks = bp.getPendingTasks().copy();
if (session.getStatus() == IPDISession.STARTED) {
getSession().getTaskManager().getSuspendedTasks(suspendedTasks);
}
if (!suspendedTasks.isEmpty()) {
getSession().getEventRequestManager().addEventRequest(
session.getRequestFactory().getDeleteBreakpointRequest(suspendedTasks, bp, allowUpdate));
bp.getPendingTasks().andNot(suspendedTasks);
if (bp.getPendingTasks().isEmpty() && allowUpdate) {
deleteBreakpoint(bp.getBreakpointID());
}
}
}
/**
* @param bkpt
* @throws PDIException
*/
private void setLocationBreakpoint(IPDILocationBreakpoint bkpt) throws PDIException {
setPendingBreakpoint(bkpt);
if (!bkpt.isEnabled()) {
disableBreakpoint(bkpt.getTasks(), bkpt);
}
}
/**
* @param watchpoint
* @throws PDIException
*/
private void setWatchpoint(IPDIWatchpoint watchpoint) throws PDIException {
setPendingBreakpoint(watchpoint);
}
/**
* @param bkpt
* @param deferred
* @throws PDIException
*/
protected void setNewLocationBreakpoint(IPDILocationBreakpoint bkpt, boolean deferred) throws PDIException {
setLocationBreakpoint(bkpt);
addBreakpoint(bkpt);
}
}