mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 06:45:43 +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:
parent
b7829381f2
commit
5a7e047ab5
1 changed files with 85 additions and 61 deletions
|
@ -493,56 +493,53 @@ public class MIStack extends AbstractDsfService
|
||||||
protected MIFrame getMIFrame() { return fFrameDataCacheInfo.getMIFrames()[fFrameIndex]; }
|
protected MIFrame getMIFrame() { return fFrameDataCacheInfo.getMIFrames()[fFrameIndex]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
fMICommandCache.execute(
|
fMICommandCache.execute(
|
||||||
fCommandFactory.createMIStackListFrames(execDmc),
|
fCommandFactory.createMIStackListFrames(execDmc),
|
||||||
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,
|
||||||
rm.done();
|
"Invalid frame " + frameDmc, null)); //$NON-NLS-1$
|
||||||
return;
|
rm.done();
|
||||||
}
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleError() {
|
protected void handleError() {
|
||||||
// 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 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,
|
||||||
rm.done();
|
"Invalid frame " + frameDmc, null)); //$NON-NLS-1$
|
||||||
return;
|
rm.done();
|
||||||
}
|
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();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -944,17 +941,44 @@ 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(
|
||||||
else {
|
listFramesCommand,
|
||||||
super.handleError();
|
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();
|
||||||
|
}
|
||||||
|
// Create the data object. Depth is +1 of maximum frame level
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue