phil-opp / blog_os

Writing an OS in Rust
http://os.phil-opp.com
Apache License 2.0
15.68k stars 1.08k forks source link

How to debug in vscode? #1206

Open SmallHuaZi opened 1 year ago

SmallHuaZi commented 1 year ago

Hello author, I'm a new rust developer. I use vscode for rust development on linux . When writing this project, I want to debug but don't know how! This is very painful for me to learn this project. Of course, before asking this question, I used gdb and rust-gdb for remote debugging, but there are always problems in the debugging process, such as the inability to jump to the location of the source code normally, and it seems that the location of lib.rs cannot be located. can you please give me some advice, thank you!

AtomicGamer9523 commented 1 year ago

Hey, @SmallHuaZi Have you tried using rust-analyzer ?

PitchBlackNights commented 1 year ago

@SmallHuaZi If you use rust-analyzer, make sure you follow the instructions of this issue reply. It prevents rust-analyzer from screaming at you whenever you are working in a #![no-std] file

KellyMurphy commented 1 year ago

Keep in mind this isn't a standard rust app you are writing with this project, It's an Operating System Kernel. So the code is running in an isolated environment provided by QEMU just as it would run on a dedicated PC.

You might be able to do it using something like the link here: launch QEMU with the -s and -S options

If you get it working, it might be interesting to write up a blog post and share with the community how you got it working.

SmallHuaZi commented 1 year ago

Sorry brothers, I didn't follow github during this time. I know how to use qemu debugging, I've written operating systems in C++ before, but I find this project a bit too large. This is all off topic, when I use gdb or rgdb, breakpoints don't seem to work, and there seems to be some problem with the positioning of the source code, I have not been able to solve this problem, I hope you can give me some help

SPuntte commented 1 year ago

Hi @SmallHuaZi, I hope this helps.

I have experimented with remote debugging my hobby Rust OS a bit. Strangely enough, although the rustc dev guide suggests the opposite, in my experience, LLDB seems to work better than GDB. This might have something to do with the fact that the relevant information in the guide is 4 years old. Another thing to keep in mind: compared to more established languages like C or C++, Rust still has plenty room for improvement when it comes to debugging.

As previous commenters suggested, running a #![no_std] binary inside QEMU also complicates matters somewhat. I think my first (working) setup was inspired by this blog post (using the Native Debug extension). While it works, it is also far from perfect: value formatting in the VSCode UI seems unhelpful at best, hovering code with mouse frequently throws errors, and stepping in/out of certain common constructs (e.g. for loops) seems to hit a GDB bug (it crashes).

Fortunately, the CodeLLDB extension supports the gdbserver protocol as well. Writing VSCode launch.json configuration for the main binary (built from src/main.rs) is quite straightforward but it gets a bit flaky for tests (or benches) since the filenames of their compilation artifacts are not deterministic. The manual suggests that the extension can even work around that. I have not tested it though, as I had already written scripts to solve the issue for the Native Debug + GDB setup before finding out.

I suggest you take a look at my scripts plus the debugging (and task) configurations they generate. Assuming you are following along the current (second edition) blog (bootimage configured as the runner, etc.), here are the essentials:

  1. Start QEMU with cargo run -- -s -S (for debugging tests you could substitute test --lib or test --test <integration test name> for run).

  2. Attach to it from VSCode using CodeLLDB with something like the following in launch.json:

    {
       "type": "lldb",
       "request": "custom",
       "processCreateCommands": [
           "gdb-remote localhost:1234",
           "c"
       ],
       "targetCreateCommands": [
           "target create ${workspaceRoot}/target/x86_64-blog_os/debug/blog_os",
           "b _start"
       ],
       "name": "blog_os LLDB+QEMU example"
    }

At risk of stating the obvious, the c (continue) command is for overcoming the -S argument for QEMU, and b _start is to pause execution at a known good point upon debugger attach. Also, note that the target create command needs to change for debugging tests.

grtwje commented 4 months ago

Thank you @SPuntte. Your instructions were helpful.

Maybe a quirk of my setup, but I had to launch the debug target in VSCode before doing the "cargo run -- -s -S"