翻译进度
6
分块数量
0
参与人数

如何在 VSCode 中调试 Rust 代码

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


Rust

Visual Studio Code is my Rust editor of choice. Unfortunately it can't quite debug Rust out of the box.

Configuring the debugger isn't hard. But there are a few steps. I've gone through them several times now. I'm writing this guide to save future me from having to remember them.

Hopefully this guide is useful to a few other folks as well.

Install Rust and VS Code

This should go without saying.

Install Rust\
Install Visual Studio Code

Install VS Code Extensions

You'll need to install an extension. Which one depends on your platform.

C/C++ (Windows)\
CodeLLDB (OS X / Linux)\

It probably makes sense to go ahead and install the Rust extension as well.

Configure VS Code

Now that your tools are installed you need to configure your VS Code launch properties.

Click Debug -> Add Configuration\
If you're on Windows then select C++ (Windows)\
If you're on Mac or Linux then select LLDB: Custom Launch

This should create and open launch.json. You'll have to manually change the executable name under "program".

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(Windows) Launch",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "${workspaceRoot}/target/debug/foo.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}",
            "environment": [],
            "externalConsole": true
        },
        {
            "name": "(OSX) Launch",
            "type": "lldb",
            "request": "launch",
            "program": "${workspaceRoot}/target/debug/foo",
            "args": [],
            "cwd": "${workspaceRoot}",
        }
    ]
}

Text above can be copy-pasta'd.

Next, you should verify breakpoints are enabled. Some readers have reporting needing to this do. Some machines have it enabled by default. 🤷‍♂️

Breakpoint settings

File -> Preferences -> Settings

That's it!

Add a breakpoint. Press F5 to launch. Voila!

Limitations

Debugging Rust works pretty well. It's not perfect. But it's pretty good!

Basic types work fine. Assuming they aren't optimized away by the compiler, of course.

Basic Types

I've found the Rust compiler to be a little more aggressive than C++ when it comes to optimizing away "unused" variables. Sometimes I store intermediate values in variables just for the debugger. Their absence can be mildly annoying.

Vectors work just fine. Thankfully. I wish the unexpanded "preview" was more informative.

Basic Types

Unfortunately other containers don't work at all. HashMap is indecipherable crap. :(

HashMap

Visual Studio 2017 has natvis for C++. It's not great. I have a lot of complaints. It's way better than Rust's nothing.

VisualStudio2017

Mixed Debugging

While working on this post I learned something new. I'm somewhat blown away and want to share it.

I was experimenting with the microprofile library. It wasn't behaving quite like I expected so I stepped into the debugger. Much to my surprise I was able to seamlessly step into the crate's Rust code. But what really shocked me is I could also step right into it's underlying C++ code!

C++ Debugging

All of this "just works". No additional configuration needed. You don't have to manuall specify include paths.

This is awesome! You can easily step-into crate dependencies. If the crate relies on C++ code then you can debug that too.

I had no idea it was this easy. What a delightful surprise!

Example Project

I've put together a small sample project with launch.json pre-configured. This should "just work".

  1. Run cargo build
  2. Open .vscode/ws.code-workspace
  3. Add a breakpoint
  4. Select your debug launch config
  5. Press F5

Example folder structures:

Rust

Cargo.toml

[package]
name = "vscode_debug_example"
version = "0.1.0"
authors = ["Forrest Smith <forrestthewoods@gmail.com>"]
edition = "2018"

[dependencies]
microprofile = "0.0.2"
rand = "0.6.5"

src/main.rs

use rand::*;
use std::collections::HashMap;
#[macro_use]
extern crate microprofile;

fn some_test_func() -> i32 {
    let mut sorted_nums = vec![5, 2, 6, 4, 3, 1];
    sorted_nums.sort();
    let result = sorted_nums.iter().sum();
    result
}

fn some_func() {
    another_func();
}

fn another_func() {
    one_more_func();
}

fn one_more_func() {
    microprofile::shutdown();
}

#[allow(unused)]
fn main() {
    // Hello
    println!("Hello, world!");

    // Numbers
    let mut i = 5;
    i += 3;
    let f: f32 = 42.0;

    // Strings
    let s = "SomeString";
    let t = "SomeOtherString";
    let mut u: String = "The".to_string();
    u.push_str("ThirdString");

    // Vec; works pretty well!
    let nums = vec![1, 2, 3, 4, 5];

    // HashMap; does not work well :(
    let mut map = HashMap::<String, String>::new();
    map.insert("some_key".to_string(), "some_value".to_string());
    map.insert("some_other_key".to_string(), "some_other_value".to_string());

    // Stepping in the random crate
    let x: u8 = random();
    let y = random::<f64>();

    // Profile (C++)
    microprofile::init();
    {
        microprofile::scope!("group", "test");
        let result = some_test_func();
    }
    some_func();
    //microprofile::shutdown();

    // Goodbye
    println!("Goodbye cruel world");
}

Final Thoughts

I love debuggers. Using VS Code to debug Rust isn't perfect, but it's pretty good. This guide should have everything you need to get started.

This should work on any platform. However I've only tested Windows and OS X. If I'm missing a step or the process changes please let me know.

Thanks for reading.

本文章首发在 LearnKu.com 网站上。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://www.forrestthewoods.com/blog/how...

译文地址:https://learnku.com/rust/t/36706

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!