Support stack frames pagination for a thread
timonag opened this issue · 2 comments
At this moment EnumFrameInfo
method reads parameters info for all stack frames of a thread in spite of a client requesting a range of them (e.g. vscode-cpptools by default requests only the first 20 frames).
Finally the HandleStackTraceRequestAsync
handler replies to a client with a requested slice of frames. It means that some resources were wasted and it creates a significant delay on large stacks.
Is it possible to pass start and end frame level into the EnumFrameInfo
to get necessary info only?
EnumFrameInfo
only has to return a IEnumDebugFrameInfo2
.
At the moment, EnumFrameInfo
grabs all the stack frames and caches it into an AD7FrameInfoEnum.
But the code can be modified to retrieve frames based on IEnumDebugFrameInfo2.Take(...)
and ignore frames with IEnumDebugFrameInfo2.Skip(...)
.
Reference:
MIEngine/src/MIDebugEngine/AD7.Impl/AD7Thread.cs
Lines 110 to 160 in 8456c49
It's fine how HandleStackTraceRequestAsync
slices stack frames according to client's needs.
The problem is about DebuggedProcess.GetParameterInfoOnly
called over all frames on the stack which is not cached and might be quite expensive:
MS_MIDebug: 1: (750055) <-1616-stack-list-arguments 0 0 49
MS_MIDebug: 1: (750065) ->1616^done,stack-args=[
frame={level="0",args=[name="x",name="v",name="v1",name="v2",name="v3",name="v4"]},
............................,
frame={level="36",args=[name="x",name="ub",name="v",name="v1",name="v2",name="v3",name="v4"]},
frame={level="37",args=[name="ub"]},
............................,
frame={level="49",args=[]}]
MS_MIDebug: 1: (750285) <-1629-stack-select-frame 1
.......
MS_MIDebug: 1: (759576) <-2184-stack-select-frame 42
If I patch the method:
int IDebugThread201(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, uint startFrame, uint endFrame, out IEnumDebugFrameInfo2 enumObject) {
......
uint low = Math.Max(stackFrames[0].Level, startFrame);
uint high = Math.Min(stackFrames[stackFrames.Count - 1].Level, endFrame);
......
}
Then it works great. First a breakpoint is hit:
MS_MIDebug: 1: (15842) <-1027-stack-list-arguments 0 0 20
.....
MS_MIDebug: 1: (21016) <-1325-stack-select-frame 20
then I click Load All Stack Frames button in the VSCode:
MS_MIDebug: 1: (191412) <-1664-stack-list-arguments 0 20 49
.......
MS_MIDebug: 1: (196139) <-1935-stack-select-frame 42