Rust Debugging Quest


#1

I’ve recently started working full time to improve Rust debugging. I thought I’d post a bit about what I’m planning to do. I’m open to additions and commentary; and also I have some questions.

The main thing I’m doing first is writing a Rust plugin for lldb. This is needed in order to enable future improvements to debuginfo (see below for a case in point). I’m currently doing this work here, but at some point I suppose this should be moved to rust-lang-nursery. (Sooner or later? The first question for you.)

The plugin is maybe halfway done, with the remaining piece being expression parsing. For this I’m currently planning write an external parser using the syn crate (or perhaps libsyntax 2.0), and have lldb call into it.

For a while, I think the Rust community will have to ship a fork of lldb. This message on lldb-dev explains why. Even once the Rust plugin lands upstream, we’ll still need to ship the external parser. I talked a bit with acrichto about this, see the bug he filed.

An lldb plugin will let us evolve the debuginfo output of the compiler in parallel with fixes to the debuggers. I can write up a full list if it’s needed (many of the to-do items are in the github issues already), but some highlights are:

  • Correctly represent optimized enums. See this issue. I’ve actually implemented all of this for llvm (patches landed), rustc, and gdb – but I am having second thoughts about landing it. On the one hand, the enum optimization improvements regressed debugger support for this in some cases. On the other hand, these patches will make enums basically incomprehensible to lldb. So: land them anyway? Or hold them until the lldb plugin is done?

  • Emit debuginfo for traits. This will enable method calls via traits, and also operator overloading support.

  • Emit more debuginfo for virtual tables, allowing calls on trait objects.

  • Macro stepping. (This one doesn’t actually need the lldb port, it’s just something that keeps coming up…)

I’ll also be filing bugs against DWARF to try to get Rust bindings into the standard. There are already a couple of Rust-inspired extensions in LLVM’s DWARF output which should probably be standardized; and we’ll need some new tags as well.

One unknown is how to deal with Windows. There’s some PDB support in LLVM but it’s unclear to me how much of Rust can be expressed there.


#2

I say land them anyway. We’re going to have some churn either way, it’s okay if stuff is unstable for this year as long as we eventually settle down.


#3

Great work, @tromey! I think this will be much appreciated once the community can get their hands on it.

Some questions:

  • You say you have implemented the changes around optimized enums in LLVM, rustc, and gdb. Am I correct in assuming that only the LLVM part has landed upstream while the rustc and gdb changes are on still on personal branches that you maintain?
  • Is there a way to make gdb support both, the current format and the new one?

Depending on the answers to the question above I have two suggestions on how to move forward:

  1. If gdb cannot support both formats, we could:
    • keep the GDB changes in a fork while we still need to support the old format for LLDB,
    • make the compiler support both formats, with the new format only being emitted when a -Zdebuginfo-2018 flag is specified.
    • add a job to our CI that uses the GDB fork and tests the new format,
    • while regular users we keep using the current format.
  2. If we can make GDB support both formats,
    • we’d just land the changes in GDB,
    • land the changes in the compiler, but still behind a nightly-only flag,
    • update our tests to test both the new and the old format.

I’d like to not break current LLDB, especially as long as we don’t have an ETA for the proper Rust plugin. People are using it as far as I can tell. However, I would be fine with starting out with a minimal LLDB plugin that just maintains the level of support that we have now (i.e. no parser, no expression evaluation). If we ship that then we could just switch the compiler over to the format.

One question though is: What do we do about older versions of GDB out there? Would we just tell people “download a recent version of GDB”?


#4

Yes. The rust compiler patch is here and the gdb patch is here. I’m going to submit the gdb patch upstream soon, like probably today.

Yes, that’s what i implemented – the patch moves the current enum-handling bits into the DWARF reader, and then adds support for the new format there. So now the rust code in gdb only sees a single representation.

This is interesting. I was under the impression that you could currently evaluate expressions in LLDB, but you had to use C++ syntax. Is that not the case? Because my current Rust plugin for LLDB is basically DWARF reading without expressions – not 100% done, but close to that milestone.

Yes, I think that’s the only way. But also see this issue about shipping lldb. One idea would be to also sometimes ship our own gdb. I’ve argued against this in the past, but maybe it really is the way to go.