1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

[272736] Add more checks to know if we ran to the right place.

This commit is contained in:
Marc Khouzam 2009-04-19 19:54:27 +00:00
parent c2b2171a7e
commit 954592bc6c
3 changed files with 101 additions and 46 deletions

View file

@ -53,20 +53,23 @@ public class GDBRunControl extends MIRunControl {
private static class RunToLineActiveOperation {
private IMIExecutionDMContext fThreadContext;
private int fBpId;
private String fLocation;
private String fFileLocation;
private String fAddrLocation;
private boolean fSkipBreakpoints;
public RunToLineActiveOperation(IMIExecutionDMContext threadContext,
int bpId, String location, boolean skipBreakpoints) {
int bpId, String fileLoc, String addr, boolean skipBreakpoints) {
fThreadContext = threadContext;
fBpId = bpId;
fLocation = location;
fFileLocation = fileLoc;
fAddrLocation = addr;
fSkipBreakpoints = skipBreakpoints;
}
public IMIExecutionDMContext getThreadContext() { return fThreadContext; }
public int getBreakointId() { return fBpId; }
public String getLocation() { return fLocation; }
public String getFileLocation() { return fFileLocation; }
public String getAddrLocation() { return fAddrLocation; }
public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; }
}
@ -260,18 +263,19 @@ public class GDBRunControl extends MIRunControl {
}
if (doCanResume(context)) {
final String location = fileName + ":" + lineNo; //$NON-NLS-1$
final String fileLocation = fileName + ":" + lineNo; //$NON-NLS-1$
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class);
getConnection().queueCommand(
new MIBreakInsert(bpDmc, true, false, null, 0,
location, dmc.getThreadId()),
fileLocation, dmc.getThreadId()),
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
// We must set are RunToLineActiveOperation *before* we do the resume
// or else we may get the stopped event, before we have set this variable.
int bpId = getData().getMIBreakpoints()[0].getNumber();
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, location, skipBreakpoints);
String addr = getData().getMIBreakpoints()[0].getAddress();
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, fileLocation, addr, skipBreakpoints);
resume(context, new RequestMonitor(getExecutor(), rm) {
@Override
@ -320,12 +324,30 @@ public class GDBRunControl extends MIRunControl {
@DsfServiceEventHandler
public void eventDispatched(final MIStoppedEvent e) {
if (fRunToLineActiveOperation != null) {
String location = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
if (location.equals(fRunToLineActiveOperation.getLocation())) {
// We stopped on our temporary breakpoint. All is well.
int bpId = 0;
if (e instanceof MIBreakpointHitEvent) {
bpId = ((MIBreakpointHitEvent)e).getNumber();
}
String fileLocation = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
String addrLocation = e.getFrame().getAddress();
// Here we check three different things to see if we are stopped at the right place
// 1- The actual location in the file. But this does not work for breakpoints that
// were set on non-executable lines
// 2- The address where the breakpoint was set. But this does not work for breakpoints
// that have multiple addresses (GDB returns <MULTIPLE>.) I think that is for multi-process
// 3- The breakpoint id that was hit. But this does not work if another breakpoint
// was also set on the same line because GDB may return that breakpoint as being hit.
//
// So this works for the large majority of cases. The case that won't work is when the user
// does a runToLine to a line that is non-executable AND has another breakpoint AND
// has multiple addresses for the breakpoint. I'm mean, come on!
if (fileLocation.equals(fRunToLineActiveOperation.getFileLocation()) ||
addrLocation.equals(fRunToLineActiveOperation.getAddrLocation()) ||
bpId == fRunToLineActiveOperation.getBreakointId()) {
// We stopped at the right place. All is well.
fRunToLineActiveOperation = null;
} else {
// Didn't stop at the right line yet
// Didn't stop at the right place yet
if (fRunToLineActiveOperation.shouldSkipBreakpoints() && e instanceof MIBreakpointHitEvent) {
getConnection().queueCommand(
new MIExecContinue(fRunToLineActiveOperation.getThreadContext()),
@ -338,9 +360,8 @@ public class GDBRunControl extends MIRunControl {
// since we don't want it to hit later
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(fRunToLineActiveOperation.getThreadContext(),
IBreakpointsTargetDMContext.class);
int bpId = fRunToLineActiveOperation.getBreakointId();
getConnection().queueCommand(new MIBreakDelete(bpDmc, new int[] {bpId}),
getConnection().queueCommand(new MIBreakDelete(bpDmc, new int[] {fRunToLineActiveOperation.getBreakointId()}),
new DataRequestMonitor<MIInfo>(getExecutor(), null));
fRunToLineActiveOperation = null;
}

View file

@ -60,20 +60,23 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
private static class RunToLineActiveOperation {
private IMIExecutionDMContext fThreadContext;
private int fBpId;
private String fLocation;
private String fFileLocation;
private String fAddrLocation;
private boolean fSkipBreakpoints;
public RunToLineActiveOperation(IMIExecutionDMContext threadContext,
int bpId, String location, boolean skipBreakpoints) {
int bpId, String fileLoc, String addr, boolean skipBreakpoints) {
fThreadContext = threadContext;
fBpId = bpId;
fLocation = location;
fFileLocation = fileLoc;
fAddrLocation = addr;
fSkipBreakpoints = skipBreakpoints;
}
public IMIExecutionDMContext getThreadContext() { return fThreadContext; }
public int getBreakointId() { return fBpId; }
public String getLocation() { return fLocation; }
public String getFileLocation() { return fFileLocation; }
public String getAddrLocation() { return fAddrLocation; }
public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; }
}
@ -450,18 +453,19 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
}
if (doCanResume(context)) {
final String location = fileName + ":" + lineNo; //$NON-NLS-1$
final String fileLocation = fileName + ":" + lineNo; //$NON-NLS-1$
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class);
getConnection().queueCommand(
new MIBreakInsert(bpDmc, true, false, null, 0,
location, dmc.getThreadId()),
fileLocation, dmc.getThreadId()),
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
// We must set are RunToLineActiveOperation *before* we do the resume
// or else we may get the stopped event, before we have set this variable.
int bpId = getData().getMIBreakpoints()[0].getNumber();
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, location, skipBreakpoints);
String addr = getData().getMIBreakpoints()[0].getAddress();
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, fileLocation, addr, skipBreakpoints);
resume(context, new RequestMonitor(getExecutor(), rm) {
@Override
@ -510,12 +514,30 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
@DsfServiceEventHandler
public void eventDispatched(final MIStoppedEvent e) {
if (fRunToLineActiveOperation != null) {
String location = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
if (location.equals(fRunToLineActiveOperation.getLocation())) {
// We stopped on our temporary breakpoint. All is well.
int bpId = 0;
if (e instanceof MIBreakpointHitEvent) {
bpId = ((MIBreakpointHitEvent)e).getNumber();
}
String fileLocation = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
String addrLocation = e.getFrame().getAddress();
// Here we check three different things to see if we are stopped at the right place
// 1- The actual location in the file. But this does not work for breakpoints that
// were set on non-executable lines
// 2- The address where the breakpoint was set. But this does not work for breakpoints
// that have multiple addresses (GDB returns <MULTIPLE>.) I think that is for multi-process
// 3- The breakpoint id that was hit. But this does not work if another breakpoint
// was also set on the same line because GDB may return that breakpoint as being hit.
//
// So this works for the large majority of cases. The case that won't work is when the user
// does a runToLine to a line that is non-executable AND has another breakpoint AND
// has multiple addresses for the breakpoint. I'm mean, come on!
if (fileLocation.equals(fRunToLineActiveOperation.getFileLocation()) ||
addrLocation.equals(fRunToLineActiveOperation.getAddrLocation()) ||
bpId == fRunToLineActiveOperation.getBreakointId()) {
// We stopped at the right place. All is well.
fRunToLineActiveOperation = null;
} else {
// Didn't stop at the right line yet
// Didn't stop at the right place yet
if (fRunToLineActiveOperation.shouldSkipBreakpoints() && e instanceof MIBreakpointHitEvent) {
getConnection().queueCommand(
new MIExecContinue(fRunToLineActiveOperation.getThreadContext()),
@ -528,9 +550,8 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
// since we don't want it to hit later
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(fRunToLineActiveOperation.getThreadContext(),
IBreakpointsTargetDMContext.class);
int bpId = fRunToLineActiveOperation.getBreakointId();
getConnection().queueCommand(new MIBreakDelete(bpDmc, new int[] {bpId}),
getConnection().queueCommand(new MIBreakDelete(bpDmc, new int[] {fRunToLineActiveOperation.getBreakointId()}),
new DataRequestMonitor<MIInfo>(getExecutor(), null));
fRunToLineActiveOperation = null;
}

View file

@ -200,20 +200,23 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
private static class RunToLineActiveOperation {
private IMIExecutionDMContext fThreadContext;
private int fBpId;
private String fLocation;
private String fFileLocation;
private String fAddrLocation;
private boolean fSkipBreakpoints;
public RunToLineActiveOperation(IMIExecutionDMContext threadContext,
int bpId, String location, boolean skipBreakpoints) {
int bpId, String fileLoc, String addr, boolean skipBreakpoints) {
fThreadContext = threadContext;
fBpId = bpId;
fLocation = location;
fFileLocation = fileLoc;
fAddrLocation = addr;
fSkipBreakpoints = skipBreakpoints;
}
public IMIExecutionDMContext getThreadContext() { return fThreadContext; }
public int getBreakointId() { return fBpId; }
public String getLocation() { return fLocation; }
public String getFileLocation() { return fFileLocation; }
public String getAddrLocation() { return fAddrLocation; }
public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; }
}
@ -593,26 +596,19 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
return;
}
final String location = fileName + ":" + lineNo; //$NON-NLS-1$
final String fileLocation = fileName + ":" + lineNo; //$NON-NLS-1$
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class);
fConnection.queueCommand(
new MIBreakInsert(bpDmc, true, false, null, 0,
location, dmc.getThreadId()),
fileLocation, dmc.getThreadId()),
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
// We must set are RunToLineActiveOperation *before* we do the resume
// or else we may get the stopped event, before we have set this variable.
int bpId = getData().getMIBreakpoints()[0].getNumber();
// It would have been nice to use the address returned by the break-insert as our location,
// but that does not always work because sometimes the address is <MULTIPLE>
//
// Also, we could have used the breakpoint id to know if we hit the proper breakpoint,
// but that also doesn't always work because if there are many bp at that location,
// GDB will report hitting one of them but not all of them (although GDB does consider
// that all those bps did hit.)
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, location, skipBreakpoints);
String addr = getData().getMIBreakpoints()[0].getAddress();
fRunToLineActiveOperation = new RunToLineActiveOperation(dmc, bpId, fileLocation, addr, skipBreakpoints);
resume(dmc, new RequestMonitor(getExecutor(), rm) {
@Override
@ -737,9 +733,27 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
// First check if it is the right thread that stopped
IMIExecutionDMContext threadDmc = DMContexts.getAncestorOfType(e.getDMContext(), IMIExecutionDMContext.class);
if (fRunToLineActiveOperation.getThreadContext().equals(threadDmc)) {
String location = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
if (location.equals(fRunToLineActiveOperation.getLocation())) {
// We stopped on our temporary breakpoint. All is well.
int bpId = 0;
if (e instanceof MIBreakpointHitEvent) {
bpId = ((MIBreakpointHitEvent)e).getNumber();
}
String fileLocation = e.getFrame().getFile() + ":" + e.getFrame().getLine(); //$NON-NLS-1$
String addrLocation = e.getFrame().getAddress();
// Here we check three different things to see if we are stopped at the right place
// 1- The actual location in the file. But this does not work for breakpoints that
// were set on non-executable lines
// 2- The address where the breakpoint was set. But this does not work for breakpoints
// that have multiple addresses (GDB returns <MULTIPLE>.) I think that is for multi-process
// 3- The breakpoint id that was hit. But this does not work if another breakpoint
// was also set on the same line because GDB may return that breakpoint as being hit.
//
// So this works for the large majority of cases. The case that won't work is when the user
// does a runToLine to a line that is non-executable AND has another breakpoint AND
// has multiple addresses for the breakpoint. I'm mean, come on!
if (fileLocation.equals(fRunToLineActiveOperation.getFileLocation()) ||
addrLocation.equals(fRunToLineActiveOperation.getAddrLocation()) ||
bpId == fRunToLineActiveOperation.getBreakointId()) {
// We stopped at the right place. All is well.
fRunToLineActiveOperation = null;
} else {
// The right thread stopped but not at the right place yet
@ -755,9 +769,8 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
// since we don't want it to hit later
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(fRunToLineActiveOperation.getThreadContext(),
IBreakpointsTargetDMContext.class);
int bpId = fRunToLineActiveOperation.getBreakointId();
fConnection.queueCommand(new MIBreakDelete(bpDmc, new int[] {bpId}),
fConnection.queueCommand(new MIBreakDelete(bpDmc, new int[] {fRunToLineActiveOperation.getBreakointId()}),
new DataRequestMonitor<MIInfo>(getExecutor(), null));
fRunToLineActiveOperation = null;
}