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

Explain how to use gdb to debug the compiler #443

Open
spastorino opened this issue Sep 9, 2019 · 7 comments
Open

Explain how to use gdb to debug the compiler #443

spastorino opened this issue Sep 9, 2019 · 7 comments
Labels
A-contribution-workflows Area: contribution workflows A-debuggers Area: debuggers (lldb, gdb, WinDbg, etc.) A-devex Area: contributor developer experience C-enhancement Category: enhancement E-help-wanted Call for participation: extra help is wanted E-medium Difficulty: might require some prior knowledge or code reading T-compiler Relevant to compiler team T-libs Relevant to libs team

Comments

@spastorino
Copy link
Member

There was a discussion in Zulip about how to attach gdb to x.py.

@petrochenkov suggested running gdb --args ./build/x86_64-pc-windows-gnu/stage1/bin/rustc src/test/ui/name.rs, I think it would be great to have this explained on rustc-guide because it's a recurring question.

@mark-i-m mark-i-m added E-easy Difficulty: might be a good place for a beginner E-help-wanted Call for participation: extra help is wanted labels Sep 9, 2019
@gnzlbg
Copy link
Contributor

gnzlbg commented Sep 18, 2019

microsoft/mimalloc#77 (comment) had a similar issue, where the following command fails:

process didn't exit successfully: `/home/daan/dev/rust-mimalloc/build/bootstrap/debug/rustc --edition=2018 --crate-name rustc src/librustc/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=2 -C metadata=5e0d3eeff150bb82 -C extra-filename=-5e0d3eeff150bb82 --out-dir /home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps --target x86_64-unknown-linux-gnu -L dependency=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps -L dependency=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/release/deps --extern arena=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libarena-af9d93ef6dc08aee.rmeta --extern backtrace=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libbacktrace-12b311ad047821a8.rmeta --extern bitflags=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libbitflags-0185f8c31122856c.rmeta --extern byteorder=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libbyteorder-84431642a2d21986.rmeta --extern chalk_engine=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libchalk_engine-62466d355dbdc99a.rmeta --extern fmt_macros=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libfmt_macros-482d5e66bb772b92.rmeta --extern graphviz=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libgraphviz-f6a7dc011264b85b.rmeta --extern jobserver=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libjobserver-c8b46a25bb9da522.rmeta --extern log=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/liblog-bd0a443870ca05a1.rmeta --extern measureme=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libmeasureme-091ecbacf269a237.rmeta --extern num_cpus=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libnum_cpus-88fd2b8b876d6e21.rmeta --extern parking_lot=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libparking_lot-f9292c52c4e814ca.rmeta --extern polonius_engine=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libpolonius_engine-e88075d624331b85.rmeta --extern rustc_rayon=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_rayon-ea44b91f88f116f1.rmeta --extern rustc_rayon_core=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_rayon_core-7809f22d4704262f.rmeta --extern rustc_apfloat=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_apfloat-b58383702b0e9127.rmeta --extern rustc_data_structures=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_data_structures-8fd90ba391486a46.rmeta --extern errors=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_errors-8413b71d09c551f0.rmeta --extern rustc_fs_util=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_fs_util-2b07fd141255082a.rmeta --extern rustc_macros=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/release/deps/librustc_macros-35a0cb747106834a.so --extern rustc_target=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_target-a02958114c225952.rmeta --extern scoped_tls=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libscoped_tls-484e840675fbe6fc.rmeta --extern rustc_serialize=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libserialize-f09f146ed063c0de.rmeta --extern smallvec=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libsmallvec-739f6fdb85f68aa2.rmeta --extern syntax=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libsyntax-0fd6e4d7aa6beaaa.rmeta --extern syntax_pos=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps/libsyntax_pos-255f37cb2a800a63.rmeta -Zbinary-dep-depinfo -L native=/home/daan/dev/rust-mimalloc/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/build/backtrace-sys-1d74c3d84afd8f29/out` (signal: 11, SIGSEGV: invalid memory reference)

and while one could use gdb --args to run that command, the ./x.py invocation that causes the failure sets "all kinds of environment definitions, like RUSTC_STAGE, RUSTC_REAL, RUSTC_LIBDIR etc. " which are not part of the user's environment and which would be required to reproduce the issue.

That is, gdb --args maybe works for debugging a build failure in a particular test maybe, but it does suffice for debugging issues where, e.g., the stage0 compiler builds, but segfaults while trying to build the stage1 compiler.

@gnzlbg
Copy link
Contributor

gnzlbg commented Sep 18, 2019

So the proper way is to pass the --on-fail={cmd} flag to ./x.py, see rust-lang/rust#38686. That allows you running a command on failure.

If you pass it --on-fail=env it will print all environment variables. If you pass it --on-fail=bash it will spawn an interactive shell with the environment already properly set up. And in that shell, you can just use gdb --args {copy failed command} and that should work correctly.

@pnkfelix
Copy link
Member

If you pass it --on-fail=bash it will spawn an interactive shell with the environment already properly set up. And in that shell, you can just use gdb --args {copy failed command} and that should work correctly.

that particular usage may currently be "broken" (see rust-lang/rust#47645), but maybe we could also fix that by passing some flag to cargo to make it stop redirecting stdin/stdout? Not sure.

@peter-lyons-kehl
Copy link

peter-lyons-kehl commented Mar 8, 2023

My notes, steps and config example of how to debug library/alloc + library/core in VS Code (on x64 Linux). Probably also applicable to Mac OS on x64 + ARM, and Windows 10.

It also shows how to invoke it through GDB, but I don't know/remember GDB.

I did not use this to debug rustc itself. Please use as you see fit. If this doesn't apply to rustc much, and if std-dev-guide.rust-lang.org could make use of this, please forward/mention this to them.

Thanks to @jyn514, @the8472 and @saethlin on t-compiler/help > debugging library/core in VS Code?.

// Customize this file. Have it under your clone of rust-lang/rust > under subdirectory .vscode/, file named: launch.json.
// Contrary to common JSON format, in VS Code's `launch.json` you **can** have comments like these in this file.

// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387

/*
To enable full debug symbols for only some of rust-lang/rust's crates, edit top-level Cargo.toml
like:

[profile.release.package]
# Do not enable full symbols in config.toml (for all of rustc + libraries), as that takes forver and the resulting binary is around 1 GB.
# 1 means line numbers only, 2 means full symbols:

core.debug  = 2
alloc.debug  = 2

To test only library/alloc/tests/vec.rs > test_collect_after_iterator_clone(), run:

# under /home/pkehl/GIT/rust-tmp/

./x.py test --stage 0 --test-args=--nocapture library/alloc/
--test-args=test_collect_after_iterator_clone

# \--> 
# UPDATED: Beware: Such `x test` invocations may call two (or even more?) test binaries, like the following output.
# -->\
...
Running unittests src/lib.rs
(build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/alloc-b372bed926abc684)

running 0 tests

test result: ok...

Running tests/lib.rs
(build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/collectionstests-ee2b17751e311633)

running 1 test

# Note the names of binaries above.
# Beware: Hashes (postfixes) in these binaries are per build (or per changeset?), so they change.

-----

# Invoking just the binary (like below from GDB or VS Code) from bash

cd /home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps
./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone
# That on its own fails - it needs LD path:
# \---> --\
./collectionstests-ee2b17751e311633: error while loading shared libraries: libtest-c6e69dd31a969b23.so: cannot open shared object file: No such file or directory

# Several ways to set LD_LIBRARY_PATH= in bash. All examples are while under /home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps.

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps ./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone

# Loading local LD path only:
LD_LIBRARY_PATH=. ./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone

# Default/global LD path + local:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone

# The following sticks (in that bash session)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps

./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone

-----

# Alternative with GDB
# (still under /home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps)
#
# The following loads it up, but it most likely can't set the breakpoints:
gdb --args x test --stage 0 --test-args=--nocapture library/alloc/
--test-args=test_collect_after_iterator_clone

# The following loads it up, and it probably can set the breakpoints - someone verify, please:
gdb --args ./collectionstests-ee2b17751e311633 --nocapture test_collect_after_iterator_clone

------

The following is for VS Code. Based on CodeLLDB's website this may work on:
- Linux with glibc 2.18+ on x64, aarch64 or armhf
- Mac OS 10.10+ on x64 and  11.0+ for arm64
- Windows 10 x64.

1. Install extension CodeLLDB (`vadimcn.vscode-lldb` - https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb).

You most likely also need (and you want anyway) rust-analyzer (`rust-lang.rust-analyzer`).

In the past you needed one more extension (some C/C++ connector), but not needed anymore (part of
`rust-analyzer` now?).

You could also try Dbgee-vscode (`nullpo-head.dbgee` - https://marketplace.visualstudio.com/items?itemName=nullpo-head.dbgee). It mentions both Linux x64 and Mac OS
x64, and Rust. However, it still needs CodeLLDB. Anyway, the following steps don't use Dbgee-vscode.

1. Ctrl+Shift+P > "View: Show Run and Debug" (or Ctrl+Shift+D) - that shows a "Run and Debug"
   sidebar.

2. Create a new launch configuration (some kind of button in the "Run and Debug" sidebar), or:
   create an empty file `.vscode/launch.json`. Put content from here.

2. Set up breakpoints: click at the source editor's gutter for lines that you want to debug. If you have Settings (Ctrl+comma) >
   Editor: Line Numbers (`editor.lineNumbers`) turned on, click just left of the line number (shown in the editor).

3.  "Start Debugging" triangle-like button (or F5). Beware that sometimes VS Code doesn't attach
    well, or doesn't stop at the breakpoint. If misbehaving, restart VS Code.

4. rust-lang library test harness outputs messages like "vec::test_collect_after_iterator_clone has
   been running for over 60 seconds", but the test will continue. So you can keep debugging.

5. Any ideas of how we could automate capturing the name of the binary; invoke it and then connect VS Code to it, or pass that binary name to VS Code?
   
   Under `"configurations"` (below) we can have `"preLaunchTask"` and `"preRunCommands"`. That could run a script/hack that would extract the binary name with `sed` or similar.

   Then we store (that binary name itself) in a dedicated file under `.vscode/` or under `/tmp`.
   
   Or, even easier, but on symlink-friendly filesystems/Unix only: Make a symlink from under `.vscode/debug-binary` (or any other dedicated name), or from under the `rust-lang/rust`'s clone top directory and a dedicated file (`debug-binary` or other), to that test binary (that we captured earlier). Then `"program"` entry below could be a (constant) path to that symlink.
   
   Any other ways?
*/
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Attach to x.py",
            "program": "/home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/collectionstests-ee2b17751e311633",
            "args": ["--nocapture", "test_collect_after_iterator_clone"],
            "env": {"LD_LIBRARY_PATH": "/home/pkehl/GIT/rust-tmp/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps"}
        }
    ]
}

You may also want to cross-reference to https://std-dev-guide.rust-lang.org/development/building-and-debugging.html#println-debugging-alloc-and-core.

UPDATE:

Alternatives (for C++, but unconfirmed for Rust):

1. cppdbg

Usage of the above CodeLLDB extension implies "type": "lldb" in this launch.json configuration. Most of guides/tips on VS Code + GDB suggest "type": "cppdbg" and a VS Code extension different to the above: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools (ms-vscode.cpptools). Some guides suggest a different extension: https://marketplace.visualstudio.com/items?itemName=DamianKoper.gdb-debug, but that hasn't been maintained for over two years (as of early 2023).

2. lldb-mi

https://marketplace.visualstudio.com/items?itemName=webfreak.debug (ext install webfreak.debug) and https://github.com/lldb-tools/lldb-mi (https://aur.archlinux.org/packages/lldb-mi-git for Arch/Manjaro Linux).

3. DPC++ (?)

https://marketplace.visualstudio.com/items?itemName=intel-corporation.oneapi-gdb-debug = https://github.com/intel/vscode-oneapi-gdb-debug GPU Debug Support for Intel® oneAPI Toolkits, with SIMD Lanes view.

@peter-lyons-kehl
Copy link

Thank you to @botahamec and @repnop.

@peter-lyons-kehl
Copy link

Updated the above notes with potential alternative extensions for GDB in VS Code. Hope this helps you with navigating this space.

@jieyouxu jieyouxu added E-medium Difficulty: might require some prior knowledge or code reading C-enhancement Category: enhancement T-compiler Relevant to compiler team T-libs Relevant to libs team A-debuggers Area: debuggers (lldb, gdb, WinDbg, etc.) A-devex Area: contributor developer experience A-contribution-workflows Area: contribution workflows and removed E-easy Difficulty: might be a good place for a beginner labels Nov 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-contribution-workflows Area: contribution workflows A-debuggers Area: debuggers (lldb, gdb, WinDbg, etc.) A-devex Area: contributor developer experience C-enhancement Category: enhancement E-help-wanted Call for participation: extra help is wanted E-medium Difficulty: might require some prior knowledge or code reading T-compiler Relevant to compiler team T-libs Relevant to libs team
Projects
None yet
Development

No branches or pull requests

7 participants