DEV Community

lechat
lechat

Posted on

How to debug Rust program

Why you should know Rust

According to Stackoverflow, 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 and see how it is like.

Print debug

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

pub fn main() {
    let test = vec![100, 101, 102, 103];
    println!("{:?}", test);
}
Enter fullscreen mode Exit fullscreen mode

Result of this code:

[100, 101, 102, 103]
Enter fullscreen mode Exit fullscreen mode

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

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

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

Result of this code:

Person { name: "test", age: 20 }
Enter fullscreen mode Exit fullscreen mode

Same for enum:

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

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

Result of this code:

Apple("ringo")
Enter fullscreen mode Exit fullscreen mode

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.

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
}
Enter fullscreen mode Exit fullscreen mode

Result of this code:

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

Print debug info only in debug build

This macro which prints debug info only in debug build was provided in stackoverflow. You can test it in Playground. This code below is from the stackoverflow answer.

#[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");
    }
}
Enter fullscreen mode Exit fullscreen mode

Use breakpoints in VSCode

Rust can use breakpoints
in vscode. The following is from stackoverflow answer.

  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:
{
    "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"]
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

For your reference, in my project, I am using the following .json file. You can see there are some argument information in "args" property.

{
    "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"]
        },
    ],
}
Enter fullscreen mode Exit fullscreen mode

Then set some breakpoints in your VSCode and run "Rust Debug Launch" as follows:
Screenshot from 2020-11-08 01-55-18.png

Top comments (2)

Collapse
 
yjdoc2 profile image
YJDoc2

Great article! I learnt about the dbg macro and conditional debugging 😁
Along with these, as rust compiles to binary, one can also use gdb as one would use on c programs to debug it...but I guess vs code breakpoints would be easier...😅

Collapse
 
lechatthecat profile image
lechat • Edited

one can also use gdb as one would use on c programs to debug it

Thank you for the information, I didn't know it :)