1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 14:55:41 +02:00

Bug 458091 - Debug frames are missing or not shown in some cases

- one case where debugger fails to return stack depth, but returns
correct stack frames
- second case where debugger fails to return stack frames when asked
without limit, but can return a specific frame

Both of these are workaround for GDB bugs where it fails to return data
consistently

Change-Id: I4fb0d4e850fbce6adc655849ec3f73c85adb1bdc
Signed-off-by: Alena Laskavaia <elaskavaia.cdt@gmail.com>
This commit is contained in:
Alena Laskavaia 2015-01-21 16:27:40 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent b7829381f2
commit 5a7e047ab5

View file

@ -501,11 +501,11 @@ public class MIStack extends AbstractDsfService
// Find the index to the correct MI frame object. // Find the index to the correct MI frame object.
int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel); int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel);
if (idx == -1) { if (idx == -1) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
"Invalid frame " + frameDmc, null)); //$NON-NLS-1$
rm.done(); rm.done();
return; return;
} }
// Create the data object. // Create the data object.
rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx)); rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx));
rm.done(); rm.done();
@ -517,30 +517,27 @@ public class MIStack extends AbstractDsfService
// being asked for the stack depth or stack // being asked for the stack depth or stack
// frames, but the same command succeeds if // frames, but the same command succeeds if
// the request is limited to one frame. So try // the request is limited to one frame. So try
// again with a limit of 1. It's better to show // again for a specific frame. It's better to show
// just one frame than none at all // just one frame than none at all. Since it is only happen on error
if (miFrameDmc.fLevel == 0) { // this should not contribute much to increased traffic
fMICommandCache.execute( fMICommandCache.execute(
fCommandFactory.createMIStackListFrames(execDmc, 0, 0), fCommandFactory.createMIStackListFrames(execDmc, miFrameDmc.fLevel, miFrameDmc.fLevel),
new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) { new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
// Find the index to the correct MI frame object. // Find the index to the correct MI frame object.
int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel); int idx = findFrameIndex(getData().getMIFrames(), miFrameDmc.fLevel);
if (idx == -1) { if (idx == -1) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid frame " + frameDmc, null)); //$NON-NLS-1$ rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
"Invalid frame " + frameDmc, null)); //$NON-NLS-1$
rm.done(); rm.done();
return; return;
} }
// Create the data object. // Create the data object.
rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx)); rm.setData(new FrameDataFromMIStackFrameListInfo(getData(), idx));
rm.done(); rm.done();
} }
}); });
} else {
super.handleError();
}
} }
}); });
} }
@ -944,18 +941,45 @@ public class MIStack extends AbstractDsfService
rm.done(); rm.done();
} else { } else {
// We're seeing gdb in some cases fail when it's // We're seeing gdb in some cases fail when it's
// being asked for the stack depth or stack // being asked for the stack depth but stack frames command succeeds
// frames, but the same command succeeds if // it seems like an overkill but it will cached and ui later will ask for it anyway
// the request is limited to one frame. So try ICommand<MIStackListFramesInfo> listFramesCommand;
// again with a limit of 1. It's better to show if (maxDepth <= 0)
// just one frame than none at all listFramesCommand = fCommandFactory.createMIStackListFrames(execDmc);
if (maxDepth != 1) { else
getStackDepth(dmc, 1, rm); listFramesCommand = fCommandFactory.createMIStackListFrames(execDmc, 0, maxDepth - 1);
fMICommandCache.execute(
listFramesCommand,
new DataRequestMonitor<MIStackListFramesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
try {
// Find the maximum level in returned frames
MIFrame[] miFrames = getData().getMIFrames();
int level = 0;
for (MIFrame miFrame : miFrames) {
if (miFrame.getLevel() > level)
level = miFrame.getLevel();
} }
else { // Create the data object. Depth is +1 of maximum frame level
super.handleError(); int depth = level + 1;
fStackDepthCache.put(execDmc.getThreadId(), new StackDepthInfo(maxDepth, depth));
rm.setData(depth);
} finally {
rm.done(); // we have to close monitor no matter what
} }
} }
@Override
protected void handleError() {
// There is no point asking for stack-depth with limit of 1, lets just assume it is
// at least 1, worst case it will show error or no data on the first frame
rm.setData(1);
rm.done();
};
}
);
}
} }
}); });
} else { } else {