-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
service/dap: auto-loading for fully missing children of nested vars #2455
Conversation
…slices and arrays
Full disclaimer: I am not quite happy with how the support for pointers looks like right now. Detailed thoughts are in the code. |
cc @hyangah |
I am happy to abandon #2453 if you want. A couple of comments
|
Thank you for a quick response!
Only fully missing for now. Partial ones are untouched in his change.
I played with both options before sending out a prototype for interfaces and decided against that approach.
The updated test shows no evidence that your approach worked with FollowPointers=false because the value is still the old unloaded one (minus the "not loaded" label) and while you flipped noChildren=>hasChildren, you have not actually loaded those children in the test, so I don't know if the auto-loading was successful. From reading the code it seems that you would have he same issue because you mark the pointer, not the data child as partial, so when the parent is looked up, you try to reload it, which would still be subject to FollowPointers=false.
Will do this next.
It is not necessary if we use special expressions. There is already a test confirming that we can do auto-loading for any frame. |
Thanks. As long as prefetching can handle large data structure, a large number of variables in the scope without noticeable performance penalty and still allow navigating deeply nested structures, I am happy. I will drop my PR to stop wasting more time. |
// that is still to be determined. For now, clearly communicate when that happens with additional value labels. | ||
// TODO(polina): look into layered/paged loading for truncated strings, arrays, maps and structs. | ||
var reloadVariable = func(v *proc.Variable, qualifiedNameOrExpr string) (value string) { | ||
// We might be loading variables from the frame that's not topmost, so use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what a client would do, but this code lives in the same process as the debugger and has a (presumed valid) *proc.Variable object, so it can do better. It can set v.loaded to false and call v.loadValue
again. None of this is exported at the moment, and it needs to be done while holding a the target mutex.
It's more efficient and it's guaranteed to keep working with generics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied this code from the previous iteration that you blessed. I am happy to improve, but could we do that in a separate PR please? I added a TODO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…o-delve#2455) * service/dap: auto-loading for fully missing pointers, structs, maps, slices and arrays * Add call test * Add TODO Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
This change provides support for automatically reloading fully missing pointers, structs, arrays and maps (subject to partial config limits on reload). It does not attempt to reload partially loaded variables, which need a different way of handling (TBD).
This change reuses the code used for auto-loading interfaces, factored out into a helper
reloadVariable
. Since VariablesRequest focuses on looking up already loaded variables, we auto-load the children proactively when looking up their outer container variable. This allows us to update the inlined string value of the parent (but not grandparent) variable as well and avoid supplying references that resolve to nothing if auto-loading fails.Pointers loading has a couple of quirks comparing to other types. If a pointer was not loaded because
FollowPointers=false
(hypothetical for now because users have no way of altering this, but that could change if we merge this server with the rpc server), then we must flipFollowPointers=true
before reloading or surgically reload just the child data. Also discovered a new pointer use case - &, a special case in delve that returns a usable pointer-expression, which is not loaded by default even with FollowPointers=true. Because this case corresponds to 0x0 pointer address, it cannot be loaded directly, but instead by reloading its child data only. Should it be at all?This is an alternative implementation to #2453 (see comment).
Updates #1515
Updates golang/vscode-go#1052
Updates golang/vscode-go#1450