blob: 7a1cac9410758eded67b28f8d622972073994c08 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.dltk.internal.debug.core.model;
import java.net.URI;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IBreakpointManagerListener;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.dbgp.IDbgpSession;
import org.eclipse.dltk.dbgp.IDbgpSpawnpoint;
import org.eclipse.dltk.dbgp.breakpoints.DbgpBreakpointConfig;
import org.eclipse.dltk.dbgp.commands.IDbgpBreakpointCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpCoreCommands;
import org.eclipse.dltk.dbgp.commands.IDbgpSpawnpointCommands;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
import org.eclipse.dltk.debug.core.DebugOption;
import org.eclipse.dltk.debug.core.IDLTKDebugToolkit;
import org.eclipse.dltk.debug.core.IDLTKDebugToolkit2;
import org.eclipse.dltk.debug.core.ScriptDebugManager;
import org.eclipse.dltk.debug.core.model.IScriptBreakpoint;
import org.eclipse.dltk.debug.core.model.IScriptBreakpointLineMapper;
import org.eclipse.dltk.debug.core.model.IScriptBreakpointPathMapper;
import org.eclipse.dltk.debug.core.model.IScriptDebugTarget;
import org.eclipse.dltk.debug.core.model.IScriptExceptionBreakpoint;
import org.eclipse.dltk.debug.core.model.IScriptLineBreakpoint;
import org.eclipse.dltk.debug.core.model.IScriptMethodEntryBreakpoint;
import org.eclipse.dltk.debug.core.model.IScriptSpawnpoint;
import org.eclipse.dltk.debug.core.model.IScriptWatchpoint;
import org.eclipse.osgi.util.NLS;
public class ScriptBreakpointManager
implements IBreakpointListener, IBreakpointManagerListener {
final IScriptBreakpointPathMapper bpPathMapper;
final IScriptBreakpointLineMapper bpLineMapper;
private static final IDbgpSession[] NO_SESSIONS = new IDbgpSession[0];
private IDbgpSession[] sessions;
protected DbgpBreakpointConfig createBreakpointConfig(
IScriptBreakpoint breakpoint) throws CoreException {
// Enabled
boolean enabled = breakpoint.isEnabled()
&& getBreakpointManager().isEnabled();
DbgpBreakpointConfig config = new DbgpBreakpointConfig(enabled);
// Hit value
config.setHitValue(breakpoint.getHitValue());
// Hit condition
config.setHitCondition(breakpoint.getHitCondition());
// Expression
if (breakpoint.getExpressionState()) {
config.setExpression(breakpoint.getExpression());
}
if (breakpoint instanceof IScriptLineBreakpoint
&& !(breakpoint instanceof IScriptMethodEntryBreakpoint)) {
IScriptLineBreakpoint lineBreakpoint = (IScriptLineBreakpoint) breakpoint;
config.setLineNo(lineBreakpoint.getLineNumber());
}
return config;
}
/** Use makeExpression(IScriptWatchpoint) */
@Deprecated
protected static String makeWatchpointExpression(
IScriptWatchpoint watchpoint) throws CoreException {
final IDLTKDebugToolkit debugToolkit = ScriptDebugManager.getInstance()
.getDebugToolkitByDebugModel(watchpoint.getModelIdentifier());
return makeExpression(watchpoint, debugToolkit);
}
protected String makeExpression(IScriptWatchpoint watchpoint)
throws CoreException {
final IDLTKDebugToolkit debugToolkit = debugToolkitByModelId
.apply(watchpoint.getModelIdentifier());
return makeExpression(watchpoint, debugToolkit);
}
private static String makeExpression(IScriptWatchpoint watchpoint,
final IDLTKDebugToolkit debugToolkit) throws CoreException {
if (debugToolkit instanceof IDLTKDebugToolkit2) {
if (((IDLTKDebugToolkit2) debugToolkit)
.isWatchpointComplexSupported()) {
return watchpoint.getFieldName() + "|"
+ (watchpoint.getExpressionState()
? watchpoint.getExpression()
: "");
}
}
if (debugToolkit.isAccessWatchpointSupported()) {
return watchpoint.getFieldName()
+ (watchpoint.isAccess() ? '1' : '0')
+ (watchpoint.isModification() ? '1' : '0');
} else {
return watchpoint.getFieldName();
}
}
// Adding, removing, updating
protected void addBreakpoint(final IDbgpSession session,
IScriptBreakpoint breakpoint) throws CoreException, DbgpException {
if (!target.supportsBreakpoint(breakpoint))
return;
final IDbgpCoreCommands commands = session.getCoreCommands();
DbgpBreakpointConfig config = createBreakpointConfig(breakpoint);
String id = null;
URI bpUri = null;
// map the outgoing uri if we're a line breakpoint
if (breakpoint instanceof IScriptLineBreakpoint) {
IScriptLineBreakpoint bp = (IScriptLineBreakpoint) breakpoint;
bpUri = bpPathMapper.map(bp.getResourceURI());
}
// Type specific
if (breakpoint instanceof IScriptWatchpoint) {
IScriptWatchpoint watchpoint = (IScriptWatchpoint) breakpoint;
config.setExpression(makeExpression(watchpoint));
config.setLineNo(watchpoint.getLineNumber());
if (bpLineMapper != null) {
bpLineMapper.toDebuggerBreakpoint(bpUri, config.getLineNo(),
config);
}
id = commands.setWatchBreakpoint(bpUri, config.getLineNo(), config);
} else if (breakpoint instanceof IScriptMethodEntryBreakpoint) {
IScriptMethodEntryBreakpoint entryBreakpoint = (IScriptMethodEntryBreakpoint) breakpoint;
if (entryBreakpoint.breakOnExit()) {
final String exitId = commands.setReturnBreakpoint(bpUri,
entryBreakpoint.getMethodName(), config);
entryBreakpoint.setExitBreakpointId(exitId);
}
if (entryBreakpoint.breakOnEntry()) {
final String entryId = commands.setCallBreakpoint(bpUri,
entryBreakpoint.getMethodName(), config);
entryBreakpoint.setEntryBreakpointId(entryId);
}
} else if (breakpoint instanceof IScriptLineBreakpoint) {
IScriptLineBreakpoint lineBreakpoint = (IScriptLineBreakpoint) breakpoint;
config.setLineNo(lineBreakpoint.getLineNumber());
if (bpLineMapper != null) {
bpLineMapper.toDebuggerBreakpoint(bpUri, config.getLineNo(),
config);
}
if (ScriptBreakpointUtils.isConditional(lineBreakpoint)) {
id = commands.setConditionalBreakpoint(bpUri,
config.getLineNo(), config);
} else {
id = commands.setLineBreakpoint(bpUri, config.getLineNo(),
config);
}
} else if (breakpoint instanceof IScriptExceptionBreakpoint) {
IScriptExceptionBreakpoint lineBreakpoint = (IScriptExceptionBreakpoint) breakpoint;
id = commands.setExceptionBreakpoint(lineBreakpoint.getTypeName(),
config);
}
// Identifier
breakpoint.setId(session, id);
}
private void addSpawnpoint(final IDbgpSession session,
IScriptSpawnpoint spawnpoint) throws DbgpException, CoreException {
if (!target.supportsBreakpoint(spawnpoint))
return;
final IDbgpSpawnpointCommands commands = session
.get(IDbgpSpawnpointCommands.class);
final IDbgpSpawnpoint p = commands.setSpawnpoint(
bpPathMapper.map(spawnpoint.getResourceURI()),
spawnpoint.getLineNumber(), spawnpoint.isEnabled());
if (p != null) {
spawnpoint.setId(session, p.getId());
}
}
protected void changeBreakpoint(final IDbgpSession session,
IScriptBreakpoint breakpoint) throws DbgpException, CoreException {
if (!target.supportsBreakpoint(breakpoint))
return;
final IDbgpBreakpointCommands commands = session.getCoreCommands();
URI bpUri = null;
// map the outgoing uri if we're a line breakpoint
if (breakpoint instanceof IScriptLineBreakpoint) {
IScriptLineBreakpoint bp = (IScriptLineBreakpoint) breakpoint;
bpUri = bpPathMapper.map(bp.getResourceURI());
}
if (breakpoint instanceof IScriptMethodEntryBreakpoint) {
DbgpBreakpointConfig config = createBreakpointConfig(breakpoint);
IScriptMethodEntryBreakpoint entryBreakpoint = (IScriptMethodEntryBreakpoint) breakpoint;
String entryId = entryBreakpoint.getEntryBreakpointId();
if (entryBreakpoint.breakOnEntry()) {
if (entryId == null) {
// Create entry breakpoint
entryId = commands.setCallBreakpoint(bpUri,
entryBreakpoint.getMethodName(), config);
entryBreakpoint.setEntryBreakpointId(entryId);
} else {
// Update entry breakpoint
commands.updateBreakpoint(entryId, config);
}
} else {
if (entryId != null) {
// Remove existing entry breakpoint
commands.removeBreakpoint(entryId);
entryBreakpoint.setEntryBreakpointId(null);
}
}
String exitId = entryBreakpoint.getExitBreakpointId();
if (entryBreakpoint.breakOnExit()) {
if (exitId == null) {
// Create exit breakpoint
exitId = commands.setReturnBreakpoint(bpUri,
entryBreakpoint.getMethodName(), config);
entryBreakpoint.setExitBreakpointId(exitId);
} else {
// Update exit breakpoint
commands.updateBreakpoint(exitId, config);
}
} else {
if (exitId != null) {
// Remove exit breakpoint
commands.removeBreakpoint(exitId);
entryBreakpoint.setExitBreakpointId(null);
}
}
} else {
// All other breakpoints
final String id = breakpoint.getId(session);
if (id != null) {
final DbgpBreakpointConfig config = createBreakpointConfig(
breakpoint);
if (breakpoint instanceof IScriptWatchpoint) {
config.setExpression(
makeExpression((IScriptWatchpoint) breakpoint));
}
commands.updateBreakpoint(id, config);
}
}
}
protected static void removeBreakpoint(IDbgpSession session,
IScriptBreakpoint breakpoint) throws DbgpException, CoreException {
final IDbgpBreakpointCommands commands = session.getCoreCommands();
final String id = breakpoint.removeId(session);
if (id != null) {
commands.removeBreakpoint(id);
}
if (breakpoint instanceof IScriptMethodEntryBreakpoint) {
IScriptMethodEntryBreakpoint entryBreakpoint = (IScriptMethodEntryBreakpoint) breakpoint;
final String entryId = entryBreakpoint.getEntryBreakpointId();
if (entryId != null) {
commands.removeBreakpoint(entryId);
}
final String exitId = entryBreakpoint.getExitBreakpointId();
if (exitId != null) {
commands.removeBreakpoint(exitId);
}
}
}
private static final int NO_CHANGES = 0;
private static final int MINOR_CHANGE = 1;
private static final int MAJOR_CHANGE = 2;
private int hasBreakpointChanges(IMarkerDelta delta,
IScriptBreakpoint breakpoint) {
final String[] attrs = breakpoint.getUpdatableAttributes();
try {
final IMarker marker = delta.getMarker();
for (int i = 0; i < attrs.length; ++i) {
final String attr = attrs[i];
final Object oldValue = delta.getAttribute(attr);
final Object newValue = marker.getAttribute(attr);
if (oldValue == null) {
if (newValue != null) {
return classifyBreakpointChange(delta, breakpoint,
attr);
}
continue;
}
if (newValue == null) {
return classifyBreakpointChange(delta, breakpoint, attr);
}
if (!oldValue.equals(newValue)) {
return classifyBreakpointChange(delta, breakpoint, attr);
}
}
} catch (CoreException e) {
DLTKDebugPlugin.log(e);
}
return NO_CHANGES;
}
private static int hasSpawnpointChanges(IMarkerDelta delta,
IScriptBreakpoint breakpoint) {
final String[] attrs = breakpoint.getUpdatableAttributes();
try {
final IMarker marker = delta.getMarker();
for (int i = 0; i < attrs.length; ++i) {
final String attr = attrs[i];
if (IBreakpoint.ENABLED.equals(attr)
|| IMarker.LINE_NUMBER.equals(attr)) {
final Object oldValue = delta.getAttribute(attr);
final Object newValue = marker.getAttribute(attr);
if (oldValue == null) {
if (newValue != null) {
return IMarker.LINE_NUMBER.equals(attr)
? MAJOR_CHANGE
: MINOR_CHANGE;
}
continue;
}
if (newValue == null) {
return IMarker.LINE_NUMBER.equals(attr) ? MAJOR_CHANGE
: MINOR_CHANGE;
}
if (!oldValue.equals(newValue)) {
return IMarker.LINE_NUMBER.equals(attr) ? MAJOR_CHANGE
: MINOR_CHANGE;
}
}
}
} catch (CoreException e) {
DLTKDebugPlugin.log(e);
}
return NO_CHANGES;
}
private int classifyBreakpointChange(IMarkerDelta delta,
IScriptBreakpoint breakpoint, String attr) throws CoreException {
final boolean conditional = ScriptBreakpointUtils
.isConditional(breakpoint);
if (conditional && AbstractScriptBreakpoint.EXPRESSION.equals(attr)) {
return MAJOR_CHANGE;
}
final boolean oldExprState = delta
.getAttribute(AbstractScriptBreakpoint.EXPRESSION_STATE, false);
final String oldExpr = delta
.getAttribute(AbstractScriptBreakpoint.EXPRESSION, null);
if (ScriptBreakpointUtils.isConditional(oldExprState,
oldExpr) != conditional) {
return MAJOR_CHANGE;
}
if (IMarker.LINE_NUMBER.equals(attr) && !target.getOptions()
.get(DebugOption.DBGP_BREAKPOINT_UPDATE_LINE_NUMBER)) {
return MAJOR_CHANGE;
}
return MINOR_CHANGE;
}
// DebugTarget
private final IScriptDebugTarget target;
private final IBreakpointManager breakpointManager;
private final Function<String, IDLTKDebugToolkit> debugToolkitByModelId;
private static void changeSpawnpoint(final IDbgpSession session,
IScriptSpawnpoint spawnpoint) throws DbgpException, CoreException {
final IDbgpSpawnpointCommands commands = session
.get(IDbgpSpawnpointCommands.class);
if (commands != null) {
final String id = spawnpoint.getId(session);
if (id != null) {
commands.updateSpawnpoint(id, spawnpoint.isEnabled());
}
}
}
protected void removeSpawnpoint(final IDbgpSession session,
IScriptSpawnpoint spawnpoint) throws DbgpException, CoreException {
final IDbgpSpawnpointCommands commands = session
.get(IDbgpSpawnpointCommands.class);
if (commands != null) {
final String id = spawnpoint.getId(session);
if (id != null) {
commands.removeSpawnpoint(id);
spawnpoint.setId(session, null);
}
}
}
public ScriptBreakpointManager(IScriptDebugTarget target,
IScriptBreakpointPathMapper pathMapper,
IScriptBreakpointLineMapper lineMapper,
IBreakpointManager breakpointManager,
Function<String, IDLTKDebugToolkit> debugToolkitByModelId) {
this.target = Objects.requireNonNull(target);
this.debugToolkitByModelId = Objects
.requireNonNull(debugToolkitByModelId);
this.bpPathMapper = Objects.requireNonNull(pathMapper);
this.bpLineMapper = Objects.requireNonNull(lineMapper);
this.sessions = NO_SESSIONS;
this.breakpointManager = breakpointManager;
}
public boolean supportsBreakpoint(IBreakpoint breakpoint) {
return target.supportsBreakpoint(breakpoint);
}
private void threadAccepted() {
IBreakpointManager manager = getBreakpointManager();
manager.addBreakpointListener(target);
manager.addBreakpointManagerListener(this);
}
private IBreakpointManager getBreakpointManager() {
return breakpointManager;
}
public void threadTerminated() {
IBreakpointManager manager = getBreakpointManager();
manager.removeBreakpointListener(target);
manager.removeBreakpointManagerListener(this);
if (bpPathMapper instanceof IScriptBreakpointPathMapperExtension) {
((IScriptBreakpointPathMapperExtension) bpPathMapper).clearCache();
}
}
synchronized IDbgpSession[] getSessions() {
return sessions;
}
private synchronized boolean addSession(IDbgpSession session) {
for (int i = 0; i < sessions.length; ++i) {
if (session.equals(sessions[i])) {
return false;
}
}
final IDbgpSession[] temp = new IDbgpSession[sessions.length + 1];
System.arraycopy(sessions, 0, temp, 0, sessions.length);
temp[sessions.length] = session;
sessions = temp;
return true;
}
synchronized boolean removeSession(IDbgpSession session) {
for (int i = 0; i < sessions.length; ++i) {
if (session.equals(sessions[i])) {
if (sessions.length == 1) {
sessions = NO_SESSIONS;
} else {
final IDbgpSession[] temp = new IDbgpSession[sessions.length
- 1];
if (i > 0) {
System.arraycopy(sessions, 0, temp, 0, i);
}
++i;
if (i < sessions.length) {
System.arraycopy(sessions, i, temp, i - 1,
sessions.length - i);
}
sessions = temp;
}
return true;
}
}
return false;
}
public void initializeSession(IDbgpSession session,
IProgressMonitor monitor) {
if (!addSession(session)) {
return;
}
IBreakpoint[] breakpoints = getBreakpointManager()
.getBreakpoints(target.getModelIdentifier());
monitor.beginTask(Util.EMPTY_STRING, breakpoints.length);
for (int i = 0; i < breakpoints.length; i++) {
try {
final IBreakpoint breakpoint = breakpoints[i];
if (breakpoint instanceof IScriptSpawnpoint) {
addSpawnpoint(session, (IScriptSpawnpoint) breakpoint);
} else {
addBreakpoint(session, (IScriptBreakpoint) breakpoint);
}
} catch (Exception e) {
DLTKDebugPlugin.logWarning(
NLS.bind(Messages.ErrorSetupDeferredBreakpoints,
e.getMessage()),
e);
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
monitor.worked(1);
}
threadAccepted();
monitor.done();
}
private static class TemporaryBreakpoint implements IDebugEventSetListener {
final ScriptBreakpointManager manager;
final Map<IDbgpSession, String> ids = new IdentityHashMap<>(1);
/**
* @param manager
* @param uri
* @param line
*/
public TemporaryBreakpoint(ScriptBreakpointManager manager, URI uri,
int line) {
this.manager = manager;
final IDbgpSession[] sessions = manager.getSessions();
for (int i = 0; i < sessions.length; ++i) {
DbgpBreakpointConfig config = new DbgpBreakpointConfig(true);
try {
final String id = sessions[i].getCoreCommands()
.setLineBreakpoint(uri, line, config);
if (id != null) {
ids.put(sessions[i], id);
}
} catch (DbgpException e) {
DLTKDebugPlugin.log(e);
}
}
}
@Override
public void handleDebugEvents(DebugEvent[] events) {
for (int i = 0; i < events.length; ++i) {
DebugEvent event = events[i];
if (event.getKind() == DebugEvent.SUSPEND) {
removeBreakpoint();
DebugPlugin.getDefault().removeDebugEventListener(this);
break;
}
}
}
private void removeBreakpoint() {
try {
final IDbgpSession[] sessions = manager.getSessions();
for (int i = 0; i < sessions.length; ++i) {
final IDbgpSession session = sessions[i];
final String id = ids.remove(session);
if (id != null) {
session.getCoreCommands().removeBreakpoint(id);
}
}
} catch (DbgpException e) {
DLTKDebugPlugin.log(e);
}
}
}
public void setBreakpointUntilFirstSuspend(URI uri, int line) {
uri = bpPathMapper.map(uri);
final TemporaryBreakpoint temp = new TemporaryBreakpoint(this, uri,
line);
if (!temp.ids.isEmpty()) {
DebugPlugin.getDefault().addDebugEventListener(temp);
}
}
// IBreakpointListener
@Override
public void breakpointAdded(final IBreakpoint breakpoint) {
if (!target.supportsBreakpoint(breakpoint)) {
return;
}
final IDbgpSession[] sessions = getSessions();
for (int i = 0; i < sessions.length; ++i) {
final IDbgpSession session = sessions[i];
scheduleBackgroundOperation(target, () -> {
try {
if (breakpoint instanceof IScriptSpawnpoint) {
addSpawnpoint(session, (IScriptSpawnpoint) breakpoint);
} else {
addBreakpoint(session, (IScriptBreakpoint) breakpoint);
}
} catch (Exception e) {
DLTKDebugPlugin.log(e);
}
});
}
}
/**
* @see IBreakpointListener#breakpointChanged(IBreakpoint, IMarkerDelta)
* @param breakpoint
* @param delta
* if delta is <code>null</code> then there was a call
* to
* BreakPointManager.fireBreakpointChanged(IBreakpoint
* breakpoint), so see it as a major change.
*/
@Override
public void breakpointChanged(final IBreakpoint breakpoint,
final IMarkerDelta delta) {
if (!target.supportsBreakpoint(breakpoint)) {
return;
}
if (breakpoint instanceof IScriptSpawnpoint) {
final int changes = delta != null
? hasSpawnpointChanges(delta,
(IScriptSpawnpoint) breakpoint)
: MAJOR_CHANGE;
if (changes != NO_CHANGES) {
final IDbgpSession[] sessions = getSessions();
for (int i = 0; i < sessions.length; ++i) {
final IDbgpSession session = sessions[i];
scheduleBackgroundOperation(target, () -> {
try {
if (changes == MAJOR_CHANGE) {
removeSpawnpoint(session,
(IScriptSpawnpoint) breakpoint);
addSpawnpoint(session,
(IScriptSpawnpoint) breakpoint);
} else {
changeSpawnpoint(session,
(IScriptSpawnpoint) breakpoint);
}
} catch (Exception e) {
DLTKDebugPlugin.logError(e.getMessage(), e);
}
});
}
}
} else {
final IScriptBreakpoint sbp = (IScriptBreakpoint) breakpoint;
final int changes = delta != null ? hasBreakpointChanges(delta, sbp)
: MAJOR_CHANGE;
if (changes != NO_CHANGES) {
final IDbgpSession[] sessions = getSessions();
for (int i = 0; i < sessions.length; ++i) {
final IDbgpSession session = sessions[i];
scheduleBackgroundOperation(target, () -> {
try {
if (changes == MAJOR_CHANGE) {
removeBreakpoint(session, sbp);
addBreakpoint(session, sbp);
} else {
changeBreakpoint(session, sbp);
}
} catch (Exception e) {
DLTKDebugPlugin.logError(e.getMessage(), e);
}
});
}
}
}
}
@Override
public void breakpointRemoved(final IBreakpoint breakpoint,
final IMarkerDelta delta) {
if (!target.supportsBreakpoint(breakpoint)) {
return;
}
final IDbgpSession[] sessions = getSessions();
for (int i = 0; i < sessions.length; ++i) {
final IDbgpSession session = sessions[i];
scheduleBackgroundOperation(target, () -> {
try {
if (breakpoint instanceof IScriptSpawnpoint) {
removeSpawnpoint(session,
(IScriptSpawnpoint) breakpoint);
} else {
removeBreakpoint(session,
(IScriptBreakpoint) breakpoint);
}
} catch (Exception e) {
DLTKDebugPlugin.log(e);
}
});
}
}
// IBreakpointManagerListener
@Override
public void breakpointManagerEnablementChanged(boolean enabled) {
IBreakpoint[] breakpoints = getBreakpointManager()
.getBreakpoints(target.getModelIdentifier());
final IDbgpSession[] sessions = getSessions();
for (int i = 0; i < breakpoints.length; ++i) {
final IBreakpoint breakpoint = breakpoints[i];
for (int j = 0; j < sessions.length; ++j) {
final IDbgpSession session = sessions[j];
scheduleBackgroundOperation(target, () -> {
try {
if (breakpoint instanceof IScriptSpawnpoint) {
changeSpawnpoint(session,
(IScriptSpawnpoint) breakpoint);
} else {
changeBreakpoint(session,
(IScriptBreakpoint) breakpoint);
}
} catch (Exception e) {
DLTKDebugPlugin.log(e);
}
});
}
}
}
private static void scheduleBackgroundOperation(
final IScriptDebugTarget target, final Runnable runnable) {
String name = target.getLaunch().getLaunchConfiguration().getName();
Job breakpointBackgroundJob = new Job("Update target breakpoints: " //$NON-NLS-1$
+ name) {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
runnable.run();
} catch (Exception r) {
DLTKDebugPlugin.logError(r.getMessage(), r);
}
return Status.OK_STATUS;
}
};
breakpointBackgroundJob.setSystem(true);
breakpointBackgroundJob.schedule();
}
}