1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

Bug 506950 - Moving conditional breakpoint to different location can

break synchronization between CDT and GDB

Change-Id: I29e00ae16aba3f7a3b7e035547ad3bcae29afdf8
This commit is contained in:
Mikhail Khodjaiants 2016-11-08 15:55:09 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent a0a959db9d
commit cce9a941af

View file

@ -22,6 +22,7 @@
package org.eclipse.cdt.dsf.mi.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@ -808,9 +809,32 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
*
* @since 4.2
*/
public void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc,
final ICBreakpoint breakpoint, final RequestMonitor rm)
{
public void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint, RequestMonitor rm) {
// Remove all relevant target filters
// Note that this call is important if a breakpoint is removed directly
// from the gdb console, or else we will try to re-install it (bug 433044)
removeAllTargetFilters(dmc, breakpoint);
// Remove breakpoint problem marker (if any)
removeBreakpointProblemMarker(breakpoint);
doUninstallBreakpoint(dmc, breakpoint, new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
platformBPs.remove(breakpoint);
super.handleSuccess();
}
});
}
/*
* Un-install the target breakpoints associated with the given platform breakpoint.
* The information related to the platform breakpoints is not cleared from the session.
* This allows the target breakpoints to be re-installed when an attribute of the platform
* breakpoint is changed.
*/
private void doUninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint, final RequestMonitor rm) {
// Retrieve the breakpoint maps
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
assert platformBPs != null;
@ -824,14 +848,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
final Map<ICBreakpoint, Set<String>> threadsIDs = fPlatformToBPThreadsMaps.get(dmc);
assert threadsIDs != null;
// Remove all relevant target filters
// Note that this call is important if a breakpoint is removed directly
// from the gdb console, or else we will try to re-install it (bug 433044)
removeAllTargetFilters(dmc, breakpoint);
// Remove breakpoint problem marker (if any)
removeBreakpointProblemMarker(breakpoint);
// Minimal validation
if (!platformBPs.containsKey(breakpoint) || !breakpointIDs.containsKey(breakpoint) || !targetBPs.containsValue(breakpoint)) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_REMOVED, null));
@ -845,7 +861,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
@Override
protected void handleSuccess() {
// Update the mappings
platformBPs.remove(breakpoint);
threadsIDs.remove(breakpoint);
fPendingRequests.remove(breakpoint);
@ -942,6 +957,12 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
// some attribute might have changed which will make the install succeed.
if (!breakpointIDs.containsKey(breakpoint) && !targetBPs.containsValue(breakpoint)) {
if (!filtered) {
// Do not try to re-install the breakpoint if the change event is the result of changes
// in the breakpoint's install count.
// Excluding ATTR_DEBUGGER_PATH from the comparison because it has been set just before
// "modifyBreakpoint()" was called.
String[] diff = compareAttributes(oldValues.getAttributes(), attributes, new String[] { ATTR_DEBUGGER_PATH });
if (diff.length != 1 || !diff[0].equals(ICBreakpoint.INSTALL_COUNT)) {
attributes.put(ATTR_DEBUGGER_PATH, NULL_STRING);
attributes.put(ATTR_THREAD_FILTER, extractThreads(dmc, breakpoint));
attributes.put(ATTR_THREAD_ID, NULL_STRING);
@ -955,6 +976,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
else {
rm.done();
}
}
else {
rm.done();
}
return;
}
@ -1016,6 +1041,23 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
rm.done();
}
@Override
protected void handleError() {
// Store the error message to use in the problem marker
final String errorMessage = getStatus().getException() != null ?
getStatus().getException().getLocalizedMessage() : getStatus().getMessage();
// Try to uninstall the target breakpoints and add the problem marker
// with the error message to the platform breakpoint.
doUninstallBreakpoint(
dmc,
breakpoint,
new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
addBreakpointProblemMarker(breakpoint, errorMessage, IMarker.SEVERITY_WARNING);
rm.done();
}
@Override
protected void handleError() {
// Reset the breakpoint attributes. This will trigger a
@ -1025,8 +1067,11 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
rollbackAttributes(breakpoint, oldValues);
platformBPs.put(breakpoint, attributes);
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, getStatus().getException()));
rm.done();
};
}
);
}
};
@ -1080,10 +1125,20 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
@Override
protected void handleError() {
// Keep the old threads list and reset the attributes
// (bad attributes are the likely cause of failure)
updateRM.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
// Store the error message to use in the problem marker
final String errorMessage = getStatus().getException() != null ?
getStatus().getException().getLocalizedMessage() : getStatus().getMessage();
doUninstallBreakpoint(
dmc,
breakpoint,
new ImmediateRequestMonitor(updateRM) {
@Override
protected void handleSuccess() {
addBreakpointProblemMarker(breakpoint, errorMessage, IMarker.SEVERITY_WARNING);
updateRM.setDoneCount(0);
};
}
);
}
};
@ -1175,8 +1230,18 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
@Override
protected void handleError() {
String detailedMessage;
if (getStatus().getException() != null &&
getStatus().getException().getMessage() != null) {
detailedMessage = getStatus().getException().getMessage();
} else {
detailedMessage = getStatus().getMessage();
}
String description = (detailedMessage == null) ?
Messages.Breakpoint_attribute_problem :
MessageFormat.format(Messages.Breakpoint_attribute_detailed_problem, new Object[] { detailedMessage});
// Add the new back-end breakpoint context to the list
installRM.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
installRM.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, description, getStatus().getException()));
installRM.done();
}
});
@ -2176,4 +2241,25 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
public void removeBreakpointsTrackingListener(IMIBreakpointsTrackingListener listener) {
fTrackingListeners.remove(listener);
}
private String[] compareAttributes(Map<String, Object> oldAttr, Map<String, Object> newAttr, String[] exclude) {
List<String> list = new ArrayList<String>();
Set<String> names = new HashSet<String>(oldAttr.keySet());
names.addAll(newAttr.keySet());
for (String n : names) {
if (exclude != null && Arrays.asList(exclude).contains(n)) {
continue;
}
Object oldValue = oldAttr.get(n);
if (oldValue != null && !oldValue.equals(newAttr.get(n))) {
list.add(n);
}
else if (oldValue == null) {
if (newAttr.get(n) != null) {
list.add(n);
}
}
}
return list.toArray(new String[list.size()]);
}
}