-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Investigate replacing most of the debugger pretty-printing scripts with traits. #65564
Comments
How does this work when cross-compiling? Is it possible to easily strip this code from the executable to reduce its size while still being able to debug the binary (important for embedded)? |
@jonas-schievink You mean with remote debugging? As long as the Also, for embedded, would you have dynamic allocation? Pretty printers are mostly needed in that case. And even if you do, each of these impls would be a couple instructions (at least the above ones). |
Ah, I see. Though this sounds like it would disrupt the target state more than the current solution. Is anything similar to this implemented by other languages?
You can, yes. I suppose in that case (if you can afford a heap) the overhead of a few instructions isn't terrible but it's still a regression nonetheless. How would this be controlled? With |
👍 on the approach, this is essentially what KotlinNative is doing: calling into runtime to "reflect" values Production-grade The MVP here can be much simpler though:
|
Hm, maybe even crazier:
That way, debugger can blindly call Note that this actually can be prototyped as a crate! The only thing that the crate can't do is forcing eager instantiation of |
The problem with using
That seems... extremely complicated, compared to the debugger which already has it. Also, if DWARF type IDs are exposed in the Python scripts, then it should be trivial to get a per-type symbol name that way. |
While I like the idea, I see two problems:
|
Oh, I would prefer if this wasn't based on That is, I want the debugger to do inside, what it was doing outside, e.g. |
Just a random idea: Is is possible to store |
That wouldn't work for, say, |
I'm not sure if there is a reliable way for calling trait methods from inside debuggers yet. |
@michaelwoerister We would be exposing it as a regular function with a predictable symbol name, so that we can find it from the DWARF type information (via type ID perhaps?). |
I think we need to add the type ID as custom DWARF attribute for a type (maybe call it DW_AT_rust_type_id) to be able to access the type id from inside a debugger. |
I'm not talking about our |
I dont think that DWARF has a type id concept. I believe it only cares about offsets within a debug section.
Yes, that would be nicer than storing a type id. |
Okay so I dug into that stuff and I found how it works:
|
That is only for DWARF version 4 and higher. Only those versions support type units, which contain that value as the |
I didn't see this mentioned yet -- apologies if it has: doesn't this only work if you've got an active process? When debugging a core file, you're not going to be able to call anything. It'd be unfortunate to lose that ability. (granted, I have never actually debugged a rust process, so I don't know the current state of the type inspector script support.) EDIT: I mean, granted, debugging a coredump is probably 10-100x more likely in C/C++ land, but still... 😂 |
@uberjay I don't this it was mentioned, that's a very good point! This would also alleviate @jonas-schievink's concern with regards to remote debugging, I think, even if it may be harder to implement overall. |
…ed vec. I based this solution on my reading of: https://rethinkdb.com/blog/make-debugging-easier-with-custom-pretty-printers#what-is-still-to-be-done That post claims that there is no clean way to check for garbage pointers, and so this PR adopts the same solution of tentatively attempting to convert a dererence to a string, which throws a clean exception on garbage that we can catch and recover from. I only made the change to vec and not the other pretty printers because I wanted to focus my effort on the simplest thing that would resolve issue rust-lang#64343. In particular, I *considered* generalizing this fix to work on the other datatypes in the pretty-printing support library, but I don't want to invest effort in that until after we resolve our overall debugging support strategy; see also issues rust-lang#60826 and rust-lang#65564.
…r, r=alexcrichton made gdb pretty-printing more robust when printing uninitialized vec made gdb pretty-printing more robust when printing uninitialized vec I based this solution on my reading of: https://rethinkdb.com/blog/make-debugging-easier-with-custom-pretty-printers#what-is-still-to-be-done That post claims that there is no clean way to check for garbage pointers, and so this PR adopts the same solution of tentatively attempting to convert a dererence to a string, which throws a clean exception on garbage that we can catch and recover from. I only made the change to vec and not the other pretty printers because I wanted to focus my effort on the simplest thing that would resolve issue rust-lang#64343. In particular, I *considered* generalizing this fix to work on the other datatypes in the pretty-printing support library, but I don't want to invest effort in that until after we resolve our overall debugging support strategy; see also issues rust-lang#60826 and rust-lang#65564. Fix rust-lang#64343
…r, r=alexcrichton made gdb pretty-printing more robust when printing uninitialized vec made gdb pretty-printing more robust when printing uninitialized vec I based this solution on my reading of: https://rethinkdb.com/blog/make-debugging-easier-with-custom-pretty-printers#what-is-still-to-be-done That post claims that there is no clean way to check for garbage pointers, and so this PR adopts the same solution of tentatively attempting to convert a dererence to a string, which throws a clean exception on garbage that we can catch and recover from. I only made the change to vec and not the other pretty printers because I wanted to focus my effort on the simplest thing that would resolve issue rust-lang#64343. In particular, I *considered* generalizing this fix to work on the other datatypes in the pretty-printing support library, but I don't want to invest effort in that until after we resolve our overall debugging support strategy; see also issues rust-lang#60826 and rust-lang#65564. Fix rust-lang#64343
Something I wasn't aware of, that looks very useful: Windows This is, for example, rust/src/etc/natvis/liballoc.natvis Lines 3 to 13 in b5f265e
This looks decently declarative to me, and the more advanced features are pretty interesting. I definitely prefer it over Python code, even if it's wrapped in XML. Here's a more advanced example ( rust/src/etc/natvis/libstd.natvis Lines 28 to 49 in b5f265e
I could see this being integrated as either an unstable attribute or an associated In terms of support, VS Code even supports (a subset of) And if we come up with our own solution that can be lowered to |
natvis is indeed pretty useful! They're used by VS/VCS/WinDbg/CDB as the main means of visualizing the C++ stdlib containers, smart pointers, etc. - and they can be embedded into pdbs (as rustc does via undocumented link.exe flags) where they're automatically picked up by debuggers. They work fine on minidumps, VS can hot-reload .natvis files if they're part of your project, you can use them on third party types you don't even have source code for... there's even a non-Microsoft game console out there with natvis support in their debug engine. Cons: Using XML for a programming language is admittedly kinda horrific, and CustomListItems amounts to that. Fortunately it's typically only needed for hash/tree containers. It's also very C++ oriented - my initial PR did a bit of mangling to make Rust debug info look C++y enough for natvis to work with slices and strs (although not reliably... something to do with fat pointer types perhaps?) My own wild fantasies include auto-generating natvis files for rust enums, and teaching rust to gather and embed natvis files found in dependency crates (or maybe using build scripts to emit link args from said crates would be sufficient? I should experiment with that...) |
Interestingly, DWARF is more flexible than I thought, and it looks like at the very least I could maybe see this scaling to |
In addition to this, in gdb we normally recommend that pretty-printers not make inferior calls because it involves letting the inferior run; this can be very confusing when other threads run when you are trying to print something. Also, these calls involve stack manipulations, which is unpleasant when also trying to unwind -- gdb calls into these things when printing the stack trace. |
Overall that makes me want to go for something more like " We can do this with a |
Visited during wg-debugging triage. We think building debugger visualizations in "regular" Rust code is definitely a good idea but we agree with many of the points raised about the problems of the debugger calling into the target to render values. Additionally, users compiling with debuginfo enabled in release mode for production workloads would probably not accept needing all of this extra code in the binary which is only used at debug time. There have been various discussions about embedding (S)MIR in debuginfo which can be split from the binary and building debugger plugins that can host a proper evaluation environment. We think that is a better but more difficult route which we would like to see more fully explored. |
In the case of
Vec<T>
andString
, it would be possible to have e.g.:We would then need:
&[T]
and&str
<X as DebuggerView>::debugger_view
inX
's debuginfo<X as DebuggerView>::debugger_view
for pretty-printingI suspect there are better APIs that could accommodate more complex data structures, but I'm not sure what the limitation of the pretty-printer scripts are, around being able to call arbitrary functions.
There's also the possibility that we could encode this sort of information as data, instead of compiling it into functions, but that's probably a lot more work.
cc @michaelwoerister
The text was updated successfully, but these errors were encountered: