mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-05 23:35:48 +02:00
Bug 571161 - MIBreakpointsSynchronizer is broken in certain scenarios
- Added null check to prevent NPE. - Fixed the collector used in doTargetBreakpointsSynchronized method. Change-Id: I1ea48b9231882923fe364321e42d0202a0924bf3 Signed-off-by: Umair Sair <umair_sair@hotmail.com>
This commit is contained in:
parent
7760ce2eb7
commit
321100a2a7
1 changed files with 33 additions and 20 deletions
|
@ -15,6 +15,7 @@
|
||||||
* Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628)
|
* Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628)
|
||||||
* Jonah Graham (Kichwa Coders) - Bug 317173 - cleanup warnings
|
* Jonah Graham (Kichwa Coders) - Bug 317173 - cleanup warnings
|
||||||
* Jonah Graham (Kichwa Coders) - Bug 530377 - Corruption of state due to fast events from GDB
|
* Jonah Graham (Kichwa Coders) - Bug 530377 - Corruption of state due to fast events from GDB
|
||||||
|
* Umair Sair (Siemens) - Bug 571161 - MIBreakpointsSynchronizer is broken in certain scenarios
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.dsf.mi.service;
|
package org.eclipse.cdt.dsf.mi.service;
|
||||||
|
@ -24,6 +25,7 @@ import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -384,29 +386,35 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService
|
||||||
.getBPToPlatformMaps();
|
.getBPToPlatformMaps();
|
||||||
Stream<IBreakpointDMContext> breakpointsKnownToManager = bpToPlatformMaps.entrySet().stream()
|
Stream<IBreakpointDMContext> breakpointsKnownToManager = bpToPlatformMaps.entrySet().stream()
|
||||||
.flatMap(m -> m.getValue().keySet().stream());
|
.flatMap(m -> m.getValue().keySet().stream());
|
||||||
Collector<MIBreakpointDMContext, ?, Map<IBreakpointsTargetDMContext, String>> collector = Collectors.toMap(
|
Collector<MIBreakpointDMContext, ?, Map<IBreakpointsTargetDMContext, Set<String>>> collector = Collectors.toMap(
|
||||||
(MIBreakpointDMContext dmc) -> DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class),
|
(MIBreakpointDMContext dmc) -> DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class),
|
||||||
(MIBreakpointDMContext dmc) -> dmc.getReference());
|
(MIBreakpointDMContext dmc) -> new HashSet<>(Collections.singleton(dmc.getReference())),
|
||||||
Map<IBreakpointsTargetDMContext, String> numbersKnownToManager = breakpointsKnownToManager
|
(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toCollection(HashSet::new)));
|
||||||
|
Map<IBreakpointsTargetDMContext, Set<String>> numbersKnownToManager = breakpointsKnownToManager
|
||||||
.filter(MIBreakpointDMContext.class::isInstance).map(MIBreakpointDMContext.class::cast)
|
.filter(MIBreakpointDMContext.class::isInstance).map(MIBreakpointDMContext.class::cast)
|
||||||
.collect(collector);
|
.collect(collector);
|
||||||
|
|
||||||
for (MIBreakpoint miBpt : data.getMIBreakpoints()) {
|
for (MIBreakpoint miBpt : data.getMIBreakpoints()) {
|
||||||
String number = miBpt.getNumber();
|
String number = miBpt.getNumber();
|
||||||
if (numbersKnownToManager.values().remove(number)) {
|
|
||||||
|
boolean found = false;
|
||||||
|
for (Set<String> bpNumbers : numbersKnownToManager.values())
|
||||||
|
if (bpNumbers.remove(number))
|
||||||
|
found = true;
|
||||||
|
|
||||||
BreakpointEvent event = new BreakpointEvent();
|
BreakpointEvent event = new BreakpointEvent();
|
||||||
|
if (found)
|
||||||
event.modified = miBpt;
|
event.modified = miBpt;
|
||||||
fBreakpointEvents.addFirst(event);
|
else
|
||||||
} else {
|
|
||||||
BreakpointEvent event = new BreakpointEvent();
|
|
||||||
event.created = miBpt;
|
event.created = miBpt;
|
||||||
fBreakpointEvents.addFirst(event);
|
fBreakpointEvents.addFirst(event);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (Entry<IBreakpointsTargetDMContext, String> entry : numbersKnownToManager.entrySet()) {
|
for (Entry<IBreakpointsTargetDMContext, Set<String>> entry : numbersKnownToManager.entrySet()) {
|
||||||
IBreakpointsTargetDMContext dmc = entry.getKey();
|
IBreakpointsTargetDMContext dmc = entry.getKey();
|
||||||
String number = entry.getValue();
|
for (String number : entry.getValue())
|
||||||
if (number != null && !number.isEmpty() && (breakpointsContext == null || breakpointsContext.equals(dmc))) {
|
if (number != null && !number.isEmpty()
|
||||||
|
&& (breakpointsContext == null || breakpointsContext.equals(dmc))) {
|
||||||
BreakpointEvent event = new BreakpointEvent();
|
BreakpointEvent event = new BreakpointEvent();
|
||||||
event.deleted = number;
|
event.deleted = number;
|
||||||
fBreakpointEvents.addFirst(event);
|
fBreakpointEvents.addFirst(event);
|
||||||
|
@ -750,7 +758,9 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService
|
||||||
if (!plBpt.getCondition().equals(miBpt.getCondition())) {
|
if (!plBpt.getCondition().equals(miBpt.getCondition())) {
|
||||||
plBpt.setCondition(miBpt.getCondition());
|
plBpt.setCondition(miBpt.getCondition());
|
||||||
}
|
}
|
||||||
if (oldData.isPending() != miBpt.isPending()) {
|
// oldData can be null for notifications of breakpoints that are inserted using DSF but
|
||||||
|
// not with breakpoint service
|
||||||
|
if (oldData != null && oldData.isPending() != miBpt.isPending()) {
|
||||||
if (miBpt.isPending()) {
|
if (miBpt.isPending()) {
|
||||||
plBpt.decrementInstallCount();
|
plBpt.decrementInstallCount();
|
||||||
} else {
|
} else {
|
||||||
|
@ -801,7 +811,10 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
|
if (oldData != null)
|
||||||
contextBreakpoints.put(miBpt.getNumber(), oldData);
|
contextBreakpoints.put(miBpt.getNumber(), oldData);
|
||||||
|
else
|
||||||
|
contextBreakpoints.remove(miBpt.getNumber());
|
||||||
GdbPlugin.log(e.getStatus());
|
GdbPlugin.log(e.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1572,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceLookup.getSource(srcDmc, debuggerPath, new DataRequestMonitor<Object>(getExecutor(), rm) {
|
sourceLookup.getSource(srcDmc, debuggerPath, new DataRequestMonitor<>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
@ConfinedToDsfExecutor("fExecutor")
|
@ConfinedToDsfExecutor("fExecutor")
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue