How to debug Rust program
Tags: rust, debug, beginners
Published: 2020-11-07 23:49:37

## Why you should know Rust
According to [Stackoverflow](https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-languages-loved), Rust is the most loved language among developers. It is as fast as C/C++, but it ensures memory safety. 

But generally speaking, Rust is said to be relatively difficult language to learn. Maybe if you know how to debug Rust programs, it might be easier to understand Rust. 

By the way you can run codes written on this post on [Rust playground](https://play.rust-lang.org/) and see how it is like.

## Print debug
You can see detail of variable/struct/enum etc by println!("{:?}", variable);

```rust
pub fn main() {
    let test = vec![100, 101, 102, 103];
    println!("{:?}", test);
}
```
Result of this code:

```
[100, 101, 102, 103]
```

If you want to use this {:?}  for struct, you need to add debug attribute.

```rust
pub fn main() {
    let test = Person { name: "test", age: 20 };
    println!("{:?}", test);
}

#[derive(Debug)] // Add this
struct Person<'a> {
    name: &'a str,
    age: u8
}
```

Result of this code:

```
Person { name: "test", age: 20 }
```

Same for enum:

```rust
pub fn main() {
    let test = Fruits::Apple("ringo".to_string());
    println!("{:?}", test);
}

#[derive(Debug)] // Add this.
enum Fruits {
    Apple(String),
    Grape(String),
    Orange(String)
}
```

Result of this code:

```
Apple("ringo")
```

## dbg! macro
dbg! macro can be used in Rust1.32.0 onward. This prints what file the operation is on and in which line the operation is. 

```rust
pub fn main() {
    let people = [
        Person { name: "test1", age: 20 },
        Person { name: "test2", age: 25 },
        Person { name: "test3", age: 30 },
    ];
    dbg!(&people);
}

#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}
```

Result of this code:

```
[src/main.rs:7] &people = [
    Person {
        name: "test1",
        age: 20,
    },
    Person {
        name: "test2",
        age: 25,
    },
    Person {
        name: "test3",
        age: 30,
    },
]
```

## Print debug info only in debug build
This macro which prints debug info only in debug build was provided in [stackoverflow](https://stackoverflow.com/questions/38141056/does-rust-have-a-debug-macro). You can test it in [Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2de72998b52d70177e40b45605544b6f). This code below is from the stackoverflow answer.

```rust
#[cfg(debug_assertions)]
macro_rules! debug {
    ($x:expr) => { dbg!($x) }
}

#[cfg(not(debug_assertions))]
macro_rules! debug {
    ($x:expr) => { std::convert::identity($x) }
}

fn main() {
    let x = 4;
    debug!(x);
    if debug!(x == 5) {
        println!("x == 5");
    } else {
        println!("x != 5");
    }
}
```

## Use breakpoints in VSCode
Rust can use breakpoints 
 in vscode. The following is from [stackoverflow answer](https://stackoverflow.com/questions/37586216/step-by-step-interactive-debugger-for-rust).

1. Install VS Code.
2. Add "Rust" or "rust-analyzer" extension in your VSCode. 
3. Add "CodeLLDB" extension in your VSCode.
4. Click on the debug icon in your VSCode, then click on "add launch.json". Select LLDB from the list of debug targets.
5. Then .json file is added inside .vscode folder in the root directory of your project.
6. Open the .json file and change the inside to the following: 

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Rust Debug Launch",
            "program": "${workspaceRoot}/target/debug/${workspaceRootFolderName}",
            "args": [],
            "cwd": "${workspaceRoot}/target/debug/",
            "sourceLanguages": ["rust"]
        }
    ]
}
```

For your reference, in [my project](https://github.com/lechatthecat/oran), I am using the following .json file. You can see there are some argument information in "args" property. 

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Rust Debug Launch",
            "type": "lldb",
            "request": "launch",
            "program": "${workspaceRoot}/target/debug/${workspaceRootFolderName}",
            "args": ["--file", "${workspaceRoot}/examples/test.orn"],
            "cwd": "${workspaceRoot}/target/debug/",
            "sourceLanguages": ["rust"]
        },
    ],
}
```


Then set some breakpoints in your VSCode and run "Rust Debug Launch" as follows:
![Screenshot from 2020-11-08 01-55-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260163/9c7f5658-801e-77e4-cc4c-3c0b6e63f22b.png)