Skip to content
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

Package gdb with Rust #34457

Open
brson opened this issue Jun 24, 2016 · 36 comments
Open

Package gdb with Rust #34457

brson opened this issue Jun 24, 2016 · 36 comments
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue.

Comments

@brson
Copy link
Contributor

brson commented Jun 24, 2016

gdb has first-class support for Rust now, and two active maintainers (@tromey @Manishearth). Let's package it with Rust. This will have lots of advantages:

  • All major platforms will get the same debugging experience
  • Debuging will be more reliable because users have the exact debugger we've actually tested with our toolchain
  • By controlling the producer and consumer of our DWARF we can evolve it quickly, move to Rust-specific DWARF

Steps:

  • Set up a fork in rust-lang-nursery
  • Modify it to produce a gdb with a Rust-specific name
  • Set up CI and packaging for gdb
  • Modify rust-buildbot / rust-packaging to add gdb to the manifest as an optional component
  • Figure out the best user experience for obtaining gdb via rustup

cc @michaelwoerister @rust-lang/tools What you think?

@alexcrichton
Copy link
Member

Sounds great to me, I'm all for it!

@vadimcn
Copy link
Contributor

vadimcn commented Jun 24, 2016

I can see where you are coming from, but long term, I'd rather see LLDB standardized for Rust. I've investigated both while developing my vscode debugger front-end and here's why I chose to go with LLDB:

  • GDB only really works on Linux and even then not always (try interrupting a process via the MI API on OSX or Windows, for instance).
  • LLDB is a part of LLVM toolchain, so they are much easier to co-develop.
  • LLDB supports plugins, so there's a chance to use the actual Rust parser for expressions, rather than some hand-rolled approximation.
  • LLDB has MSVC .pdb debug info support in the works; I haven't seen any plans to do that for GDB.
  • LLDB has an actual API for embedding.

@Manishearth
Copy link
Member

LLDB being standardized for rust can happen independently of this. I was thinking of working on it; but not sure of I will (won't have time; C++ is draining).

@Manishearth
Copy link
Member

Also, until we figure out a story for DWARF in rust things are unstable anyway. We already hit the situation once where marking our binaries as DW_LANG_RUST broke lldb but was necessary for gdb to work.

@michaelwoerister
Copy link
Member

I agree with the things that @vadimcn says but I don't think that these observations necessarily speak against providing a Rust-specific GDB version.

Here are some more questions:

  1. What's the advantage of providing our own version of GDB versus just relying on Rust support getting merged upstream eventually?
  2. Can we provide an ergonomic enough experience for people to actually use this?
  3. How much maintenance effort would this mean?
  4. And, more specifically regarding the co-evolution of DWARF and GDB, will we need a "debugger-tuning" flag in the compiler? (since, at least in the beginning, LLDB will still not know about Rust)

Here are some thoughts, but I'd also like to hear how other people would answer these questions:

  1. (a) The main advantage I see is that more people would be able to profit from Rust support sooner. It can take quite a while until a change ends up in package managers and some people (like me) tend to keep using LTS versions and only upgrade when they have to.

    (b) @brson's point about providing one specific and well-tested version per platform also very good! That's something I had not thought about before.
  2. This boils down to the questions if we can make something like rustup install rust-gdb just work on Linux and OSX and hopefully on Windows too, I think. I would hope that that is not too hard on Linux, but I don't know about OSX, and GDB on Windows is always a rather brittle thing in my experience.
  3. I have no idea :)
  4. We might not quite get around that. On the other hand, there is precedent for such compiler flags.

So, I think, I'm generally in favor of this if we can pull it off with reasonable effort.

@brson
Copy link
Contributor Author

brson commented Jun 25, 2016

I can see where you are coming from, but long term, I'd rather see LLDB standardized for Rust.

I agree LLDB is more promising in the long-run, but think we should take the opportunity to do what we can now with gdb.

It's true though that if we run ahead with our own DWARF formats while favoring GDB then the LLDB support will get worse. Perhaps we'll need to leave some option to stay LLDB compatible.

What's the advantage of providing our own version of GDB versus just relying on Rust support getting merged upstream eventually?

  • We can turn on Rust-DWARF by default if we have confidence that all our users can read it. Otherwise we need to use C-compatible DWARF until we have confidence the Rust support has trickled out.
  • Even once the Rust-DWARF support gets into the world, it will be very hard to evolve because of the lag time between us changing the definition, upstream landing, and upstream's downstreams distributing.

Can we provide an ergonomic enough experience for people to actually use this?

I'd expect we can do something where you type rust-gdb (or some new command), and it says "rust-gdb is not installed, run rustup component install rust-gdb", then you're ready.

How much maintenance effort would this mean?

For us it would mean updating the gdb build we produce at least once per quarter and remediating any issues that reveals.

And, more specifically regarding the co-evolution of DWARF and GDB, will we need a "debugger-tuning" flag in the compiler? (since, at least in the beginning, LLDB will still not know about Rust)

Yeah, seems like we would need to be able to emit at least two variations of DWARF. This would present some problems with the debuginfo in std.

This boils down to the questions if we can make something like rustup install rust-gdb just work on Linux and OSX and hopefully on Windows too, I think.

The quality of Windows support worries me too. It would be a shame if we couldn't support gdb there.

@brson
Copy link
Contributor Author

brson commented Jun 25, 2016

My primary motivation for doing this is to be able to make more radical changes to our DWARF output. I'm only assuming that we need to make such changes, or have the resources to do it.

@tromey
Copy link
Contributor

tromey commented Jun 25, 2016

What's the advantage of providing our own version of GDB versus just relying on Rust support getting merged upstream eventually?

It's already merged.

And, more specifically regarding the co-evolution of DWARF and GDB, will we need a "debugger-tuning" flag in the compiler?

Probably not for gdb, but maybe for lldb.

My primary motivation for doing this is to be able to make more radical changes to our DWARF output. I'm only assuming that we need to make such changes, or have the resources to do it.

Yes, there's a need. There are a number of issues open about both errors in the generated debuginfo and also spots where more information is needed. Importing gdb into the tree isn't needed to make progress here (though you may want to do this for other reasons). I'm happy to write the gdb side upstream in parallel with rustc fixes.

The main issue I see is that there are few guards in place against rustc debuginfo regressions. 1.9 already regressed gdb's Rust support.

@Manishearth
Copy link
Member

Manishearth commented Jun 25, 2016

We could set up a build step that runs the gdb rust tests.

Build steps are straightforward and shouldn't take long:

  • Ensure DejaGnu (runtest) is installed, built rustc is in the path
  • Clone git://sourceware.org/git/binutils-gdb.git
  • make all-gdb
  • cd testsuite && make check RUNTESTFLAGS="gdb.rust/*.exp"

@Manishearth
Copy link
Member

Alternatively we could get a gdb fork to use http://nightli.es/ with a rust-specific travis test

@vadimcn
Copy link
Contributor

vadimcn commented Jun 25, 2016

My primary motivation for doing this is to be able to make more radical changes to our DWARF output. I'm only assuming that we need to make such changes, or have the resources to do it.

Yes, there's a need. There are a number of issues open about both errors in the generated debuginfo and also spots where more information is needed.

Are these things spelled out anywhere?

@tromey
Copy link
Contributor

tromey commented Jun 25, 2016

Are these things spelled out anywhere?

Yes, I filed bugs for all the problems I found. Looking at open debuginfo bugs will show them all.

Looking at this, though, I see that the most important regression was closed (for some reason I thought the patch hadn't landed); so I'll have to re-test gdb with nightly and see if it's doing better now.

Some of the remaining holes require some work on DWARF or on detailing the Rust/DWARF binding. I've been planning to write a proposal for this, though I wasn't sure if this should just be a discourse post or a full-fledged RFC. Alternatively if someone gets to this before I do, I'd be happy to comment on it.

@tromey
Copy link
Contributor

tromey commented Jun 25, 2016

Still some failures with nightly -- better than 1.9, but 1.8 was clean. I'll diagnose soon, you can follow along here.

@Manishearth
Copy link
Member

The methods failures are due to {{impl}} finding its way into method paths

@michaelwoerister
Copy link
Member

Yeah, seems like we would need to be able to emit at least two variations of DWARF. This would present some problems with the debuginfo in std.

That is a problem. Can we somehow provide two versions of the debuginfo and make the wrapper scripts add the right one to the search path?

The main issue I see is that there are few guards in place against rustc debuginfo regressions.

That's a good point. We definitely would have to include the Rust version of GDB into autotests. But that's also something that should actually become easier if we distribute our own version, right?

My primary motivation for doing this is to be able to make more radical changes to our DWARF output. I'm only assuming that we need to make such changes, or have the resources to do it.

Yes, there's a need.

I absolutely agree with @tromey. We are basically stuck if we don't co-evolve the compiler and debuginfo consumers.

Some of the remaining holes require some work on DWARF or on detailing the Rust/DWARF binding. I've been planning to write a proposal for this, though I wasn't sure if this should just be a discourse post or a full-fledged RFC. Alternatively if someone gets to this before I do, I'd be happy to comment on it.

@tromey I'd be interested in this too. What would be the best place to allow multiple people working on it?

@michaelwoerister
Copy link
Member

BTW, there might be a pretty big shift in the way LLVM handles debuginfo:
http://lists.llvm.org/pipermail/llvm-dev/2016-March/097773.html

TL;DR; DWARF or any other debuginfo might be emitted directly to LLVM IR instead of as LLVM metadata. The good thing about that is that we would have total control about what we emit and would not have to rely on LLVM merging any custom LLVM metadata => DWARF lowerings we might need.

@nrc
Copy link
Member

nrc commented Jun 27, 2016

I'm in favour of doing this. I think lowering the bar for getting good debugger support for Rust on at least one platform is very worthwhile. There is too much friction right now for a user to get to a good debugging experience.

My major worry is that we don't have the long term resources to keep this in a good place. Debuginfo in the compiler is already under-resourced and slowly bit-rotting, I fear that our gdb fork would end up in the same place, or worse.

@Manishearth
Copy link
Member

The gdb fork probably won't stay a fork, patches will keep getting upstreamed. We just maintain a fork so that we can iterate faster, and the only commits that live in the fork would be things like this special function (which could also live in rust-gdb)

On the note of rust-gdb, what is the proposed future for rust-gdb? I left a comment here, but that seems to be something better discussed in this thread.

@tromey
Copy link
Contributor

tromey commented Jun 28, 2016

@tromey I'd be interested in this too. What would be the best place to allow multiple people working on it?

I have been working on a google doc. Contact me in email and I'll share it with you. It's not nearly done yet.

@blanham
Copy link

blanham commented Jun 28, 2016

One issue with packaging GDB for macOS is that the binary needs to be codesigned in order to function.

@alexcrichton
Copy link
Member

The tools team discussed this issue during triage yesterday and the main conclusion was that we're probably not quite in a position just yet to actively ship gdb. That being said, we're very willing to actively test newer versions of gdb to ensure that our support does not regress. In other words, we're always willing to have more automation!

The major blockers we think need to be overcome before making progress on this are:

  • We need to ensure the experience is good on almost all platforms Rust supports. Right now it sounds like gdb and Rust works best on Linux, but on OSX there's worries about having to sign the binary and on Windows there's worries about gdb in general on MinGW and then also how it may interoperate with the MSVC target.
  • Blessing one debugger will likely require at least two components, effort to ensure that the Rust compiler continues to make progress in terms of what it emits, as well as effort on the debugger side to ensure that bugs are fixed and such.
  • Issues like Find strategy for evolving debuginfo format without breaking everything #34560 come up if we start having Rust-specific DWARF information.

@DemiMarie
Copy link
Contributor

Do we need to worry about man-in-the-middle attacks on the insecure git:// clone? I would definitely worry about them. If someone can do the clones who is a GDB committer they should use their ssh:// clone instead.

@Manishearth
Copy link
Member

Presumably we'd have a fork on github, so no.

@DemiMarie
Copy link
Contributor

@Manishearth how will that fork be cloned/updated?

@Manishearth
Copy link
Member

There are two of us with access to ssh gdb sources.

Though this is a very narrow threat model which I don't expect to happen, really.

@DemiMarie
Copy link
Contributor

Update: HTTPS access to GDB was broken due to a bug; this has now been fixed (at least I managed to check out the sources).

@locka99
Copy link

locka99 commented Jan 21, 2017

I'm trying to debug on Windows and I still can't do it well. TDM GDB sort of works in VSCode but step debugging is broken. At this point its easier to debug code by plastering logging all over the place and trying to pinpoint the issue.

I think shipping gdb with the stable-gcc would take a lot of guesswork out of making it work. TDM's gdb standalone is a 12MB zip so that's we're talking about sizewise

@Mark-Simulacrum Mark-Simulacrum added T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. and removed T-tools labels May 24, 2017
@Mark-Simulacrum Mark-Simulacrum added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. labels Jul 25, 2017
@tromey
Copy link
Contributor

tromey commented Feb 8, 2018

As part of my work on the Rust language plugin, I talked about shipping the plugin on the upstream list. There are two threads:

  1. The one I started. This is specifically about the Rust plugin. Somewhat interesting on its own, but a reply pointed out a different discussion:

  2. Thread about removing some other language plugins. Here the most interesting message proposes a standard for accepting new languages.

My conclusion from all of this is that we'll need some way to ship some lldb-related thing via rustup. In the short- and medium-term, this is likely to be all of lldb. In the longer term, maybe we can either ship just the Rust plugin (if lldb ever provides a way to build a language plugin out-of-tree), or just the Rust expression parser helper library/executable.

@tromey
Copy link
Contributor

tromey commented Aug 29, 2018

I've come around on this and I think it would make sense to get gdb into rustup. This would let us ship Rust improvements more quickly to users.

The main issues are around library dependencies. There's some discussion in #48168. There may also be some path issues, like finding system separate debuginfo or system gdb scripts.

@tromey
Copy link
Contributor

tromey commented Nov 21, 2018

I'm looking into this a bit. A couple possible issues:

  • gdb optionally depends on a number of libraries; the main ones are Python, expat, LZMA, and termcap. (There are a few more that can be used, but I think we can comfortably omit them.) I think most of these can be linked statically (maybe some gdb build tweak will be required). For Python my current plan is to depend on Python 2.7. Maybe we can write some kind of wrapper that will check that it is installed either at rustup time or when trying to run gdb.

  • gdb allows a few compile-time paths, like --with-separate-debug-dir. (I also saw the JIT reader dir and the system gdbinit; and possibly the default auto-load and safe paths.) A potential issue here is that different distros may put these in different places; if so, a possible fix would be to patch our gdb to adapt; or just use a path that encompasses all the common approaches.

@nrc
Copy link
Member

nrc commented Nov 26, 2018

Maybe we can write some kind of wrapper that will check that it is installed either at rustup time or when trying to run gdb.

I think a runtime wrapper will be better - especially if/when we move rustup into Cargo, we won't want to support that kind of check (although there are also vague plans for things like post-install scripts which could do this).

cc @joshtriplett for any potential distro interactions.

tromey added a commit to tromey/rust that referenced this issue Dec 18, 2018
This optionally adds gdb to the Rust build, allowing gdb to be
installed via rustup.  This makes it simpler to make debuginfo
changes, as gdb updates can now be shipped immediately.

If gdb is not checked out, nothing changes.

The build is perhaps a bit chatty, as gdb's "make" and "make install"
are run each time, even if they do nothing.

rust-gdb is modified to prefer the gdb installed by rustup.  This is
analogous to what was done for rust-lldb.

The built gdb requires Python 2.7 as a shared library (other
dependencies are statically linked).  This is a
least-common-denominator Python that is widely available and stable;
dynamic linking is used to avoid breaking existing gdb Python code
that might load shared libraries that themselves require a dynamic
libpython.  To avoid problems here, a small wrapper program is used
that attemps to dlopen libpython; with failures being reported to the
user in an intelligible way.

Two of the Linux dist builds are updated to build gdb.  More could be
added if need be.

If gdb is built as part of the build, and if no other gdb was
specified in config.toml, then the just-built gdb will be used for
debuginfo testing.

Closes rust-lang#34457
bors added a commit that referenced this issue Dec 21, 2018
Add gdb to the build

This optionally adds gdb to the Rust build, allowing gdb to be
installed via rustup.  This makes it simpler to make debuginfo
changes, as gdb updates can now be shipped immediately.

If gdb is not checked out, nothing changes.

The build is perhaps a bit chatty, as gdb's "make" and "make install"
are run each time, even if they do nothing.

rust-gdb is modified to prefer the gdb installed by rustup.  This is
analogous to what was done for rust-lldb.

The built gdb requires Python 2.7 as a shared library (other
dependencies are statically linked).  This is a
least-common-denominator Python that is widely available and stable;
dynamic linking is used to avoid breaking existing gdb Python code
that might load shared libraries that themselves require a dynamic
libpython.  To avoid problems here, a small wrapper program is used
that attemps to dlopen libpython; with failures being reported to the
user in an intelligible way.

Two of the Linux dist builds are updated to build gdb.  More could be
added if need be.

If gdb is built as part of the build, and if no other gdb was
specified in config.toml, then the just-built gdb will be used for
debuginfo testing.

Closes #34457
@tromey
Copy link
Contributor

tromey commented Jan 23, 2019

Some state here:

The PR may not be merged, as it puts gdb into the overall rust build; and this build is already quite slow, etc. Instead Alex said he'd be investigating whether gdb could be built separately and then the artifacts still distributed via rustup. This would definitely be nicer.

The PR is still of use though. It shows how to make a Dockerfile that installs the needed static dependencies. And, it patches the rust-gdb script to prefer a rustup-managed gdb if one is available; this patch should be landed if/when gdb is shipped through rustup.

There's a fork of gdb here: https://github.com/rust-dev-tools/gdb. My plan for this was to treat it like we do LLVM: keep some Rust-specific patches here (e.g., there is one to deal with the Python issue there), but otherwise keep it close to upstream. In particular, anything that would be generically useful should go upstream first, with the only divergences being things needed for the peculiarities of rustup and/or the build setup.

@workingjubilee
Copy link
Contributor

ping! It's 2020, do you know where your civilization is?

This issue was opened with the assertion that "gdb has first-class support for Rust now, and two active maintainers (@tromey @Manishearth). Let's package it with Rust."

Is this still true?

Per rust-lang/rustup#2532, it seems we currently ship a rust-gdb wrapper in Rustup, but it needs documentation. This is especially confusing to me because unlike most optional pieces of Rust, it isn't in rustup's component list, and I actually don't have gdb installed so it errors to invoke it.

@Manishearth
Copy link
Member

I don't know about tromey, but I'm not actively maintaining it (though if notified of bugs i would try to fix it). The gdb community seems to be maintaining it just fine though.

There are no active plans to package it with rust given that nobody is working on evolving rust DWARF right now and gdb support has baked for a couple years (and is present on most distribution venues).

This issue still has value in being open if we want to do this in the future. We could close it in the meantime, idk.

rust-gdb is a wrapper that sets up python pretty printers, and has existed for a really long time (before there was gdb support or even rustup). It's not clear to me if pretty printers are still necessary given the first class support, so it's worth evaluating what it does that gdb doesn't, filing gdb bugs for that behavior if possible, and getting rid of it. Some people may still use it though, so we should be careful.

TLDR it's a legacy tool that may still have use cases but as a legacy tool it's underdocumented. If folks want to work on figuring that out -- either documenting it or evaluating if it can be removed, that would be great!

@sanmai-NL
Copy link

@Manishearth Who can I ping to update https://rustc-dev-guide.rust-lang.org/debugging-support-in-rustc.html based on your info?

@Manishearth
Copy link
Member

@sanmai-NL the rustc dev guide is a repo under the rust GitHub org, you can make PRs to it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-dev-tools Relevant to the dev-tools subteam, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests