相应书:
https://learnku.com/docs/rust-lang/2018
https://doc.rust-lang.org/book/
Visual Studio Code 是我选择的 Rust 编辑器。不幸的是,它不等于能直接调试 Rust。
配置调试器并不难。但是有几个步骤。我已经经历了几次。我正在写本指南,是为了将来我们能记住。
希望本指南对其他一些人也有用。
安装 Rust 和 VS Code
这里就不用赘述了,请参考下方
Install Rust\
Install Visual Studio Code
安装 VS Code 扩展
您需要安装扩展程序。选择哪一个取决于你的平台。
C/C++ (Windows)\
CodeLLDB (OS X / Linux)\
安装这个 Rust 扩展也是很有必要的 Rust extension 。
配置 VS Code
现在 VS Code 工具已经安装完成,接下来需要配置你的 VS Code 启动项。
点击 调试 -> 添加配置 \
如果你使用的是 Windows,选择 C++ (Windows)\
如果你使用的是 Mac/Linux,选择 LLDB: Custom Launch
添加配置应该会创建并打开启动配置文件 launch.json。 你必须手动修改配置项 "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}",
}
]
}
上面的配置文本可以复制粘贴。
下一步,你应该确认已经启用断点功能。有些读者已经反馈说需要有这一步。 有些机器默认是启动该功能的
文件 -> 首选项 -> 设置
搞定!
添加一个断点。 按 F5 键启动。哇啦!
局限
使用 VS Code 调试 Rust 非常 棒。不能称之为完美,但真的非常不错。
基础类型正常运行。当然,假设它们没有被编译器优化过。
我发现,当优化 "unused" 变量时,Rust 的编译器的处理方式比 C++ 的更激进。有时我将中间值存储给变量,仅用于调试器调试。他们的缺失多少让人厌烦。
Vectors 正常运行。谢天谢地。我希望未展开的 “预览” 能提供更多信息。
不幸的是,其他容器类型根本无法工作。 HashMap
是无法被理解的废话。
Visual Studio 2017 有用于 C++ 的 Natvis 。 这些不是那么棒。我有挺多抱怨的。不过说起来,总比 Rust 什么都没有的好。
混合调试
为了写这篇文章,我学到了新东西。我有些迫不及待的想要分享它。
彼时,我正在试用库 microprofile 。它的表现跟我的预期不太一致,所以我单步调试了一下。 令我非常惊讶的是,我调试进了封装好的 Rust 代码。更令我深感震惊的是,我还可以调试进入底层的 C++ 代码!
上来就是怼。无需额外配置,没有 996,你不必手动指定包含路径。
太 6 了。你可以轻松的调试引用的封装库,如果它底层依赖了 C++ 代码,你依然可以继续调试 C++ 代码。
microprofile 用起来意想不到的简单。 当浮一大白!
示例项目
我已经整理出了一个小的示例项目,预先配置好了 launch.json
。它应该可以正常运行。
- 运行
cargo build
- 打开
.vscode/ws.code-workspace
- 添加一个断点
- 选择你的调试启动配置
- 按 F5
示例的文件夹结构:
Cargo.toml
[package]
name = "vscode_debug_example"
version = "0.1.0"
authors = ["Forrest Smith <[email protected]>"]
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!");
// 数字类型
let mut i = 5;
i += 3;
let f: f32 = 42.0;
// 字符串类型
let s = "SomeString";
let t = "SomeOtherString";
let mut u: String = "The".to_string();
u.push_str("ThirdString");
// Vec; 运行很好!
let nums = vec![1, 2, 3, 4, 5];
// HashMap; 运行效果不佳 :(
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());
// 调试进入 random 包
let x: u8 = random();
let y = random::<f64>();
// 配置调试 (C++)
microprofile::init();
{
microprofile::scope!("group", "test");
let result = some_test_func();
}
some_func();
//microprofile::shutdown();
// Goodbye
println!("Goodbye cruel world");
}
最后的一些想法
我喜欢调试器。使用 VS Code 调试 Rust 不够完美,但已经非常不错了。本篇指南有你入门开启 Rust 编程所需的一切。
示例项目应该可以在所有平台正常运行。不过,我只测试了 Windows 和 OS X 。如果某个调试步骤或者所需流程有所变化,该指南错过了它,请告诉我。