Do you know how to Debug a Rust Embedded Program?

Reading Time: 6 minutes

I hope you are done with the building and flashing of the code inside the hardware ie: stm32f3-Discovery Board. If not then you can check this blog for the same. Now it’s time to move ahead with the next step that is debugging Rust program.

You can find the code here which I am going to debug in this blog Or you can copy it from here.

use cortex_m_rt::entry;
use panic_halt;

/// This program is just used for testing the working with the micro-controller, and to debug the program.
/// This #[entry] is the entry point of the program, the point where the program halt or begin from.
fn main() -> ! {
    let value1 = 42;
    let value2 = 100;

    //using _ in front means i am telling the compiler to ignore the unused warning of value3.
    let _value3 = value1 + value2;

    // infinite loop; just so we don't leave this stack frame
    loop {}

Your program is ready for debugging after you flash the program inside the microcontroller. Before Debugging let’s know about it in short.

What is Debugging?

  • Debugging is the process of finding bugs and then resolving those bugs.
  • Bugs are known as the defects or the problem that do not allow or prevent correct operation.
  • When various subsystems or modules are tightly coupled, debugging Rust program becomes harder as any change in one module may cause more bugs to appear in another. Sometimes it takes more time to debug a program than to code it.

Let’s get started with our first debugging.

Before going ahead, check once that you have openocd running and you are connected to the port. If not then you can check out this to go with openocd and to connect with the gbd server provided by the openocd.

Let’s get started with our first debugging.
So, after you provide the “load command our program is stopped at its entry point. This is indicated by the “Start address 0x8000XXX” part of gdb’s output. The entry point is the part of a program that a processor / CPU will execute first.

Your gdb window looks like this right now.

Now the first thing you have to do is to provide the commandbreak main
you will get output like this.

Command – “break main”

A breakpoint is a spot in your program where you would like to temporarily stop execution in order to check the values of variables, or to try to find out where the program is crashing, etc. To set a breakpoint you use the break command.

break function creates a breakpoint at the beginning of the function. If your code is in multiple files, you might need to specify filename: function. Like we did here giving a function name as main to stop the execution at the beginning of the main.

Next issue a “continue command. The Output should be this.

Command – “continue”

Note* I have used c which is a short form of the continue command, just like for step n for next.

What happens here?

As you already know now breakpoints stop the normal flow of the program by setting some breakers. While the continue command sets the program to run freely without any interruption in between until it reaches a breakpoint.
Here we already applied the first breakpoint which created a breaker at [entry] and that’s why continue command our program stopped at entry line no – 9

Note* that gdb output says “Breakpoint 1“. Remember that our processor can only use six of these breakpoints so it’s a good idea to pay attention to these messages.

Command – “step”

Next, after the continue command, we need to proceed further.
Now type the “stepcommand, your output should look like this.

What step command does is, it will take the program further-statement by the statement by stepping into functions/procedures.
the step will go ahead and execute the current source line, and then stop execution again before the next source line.
Now we are inside the main program line no – 11.

Note* This line no. 11 is still not executed.

Now again type the step command and we are on line no. 12.

Note* line no. 11 is executed here but again line no 12 is not.

This is how on each “stepcommand the statement with its line no. gets printed. We are now on the let value2=100 statement; that statement hasn’t been executed yet. This means that value1 is initialized but value2 is not. Let’s inspect those local variables using the “printcommand, p for short: and find out what we get.

Now let’s try to print the value of value1 using the command print value1.

We can give one more “step” command to initialize the variable value2 then give command “print value2 ” and you can see the value 100 printed.

Similarly, put the commandstep” and _value3 will be ready to get printed and you will be on the top of the infinite loop.

This loop is infinite and if we provide any further next command then we will be stuck inside the loop.
If such conditions happen then you can hit “ctrl+c” to get out from there.

Okay, there is one command which can help you never get stuck like this.

Command – “stepi”

This command is an alternative to ctrl+c, it basically checks the coming step or statement and prints that statement and the address like this.

So the processor will know what is coming next and it won’t be stuck again.

Command “monitor reset halt”

If your program or hardware is already in the running phase and you want to debug it from starting or you want your program to get halt and hardware get reset.
monitor reset haltcommand is for you in this case. This command will take you to the beginning of the program and The continue command will then let the program run freely until it reaches a breakpoint, in this case, it is the breakpoint at #[entry].
You can roll back from the beginning if you miss something in between using the monitor reset halt command.

This is how it works. I am giving command step and falling in the loop then I am using ctrl+C to get out then using monitor reset halt -> break main -> continue.

We are done with this debugging Rust program session. You can end it with the “quitcommand.

For a nicer debugging experience, you can use GDB’s Text User Interface (TUI). To enter into that mode enter one of the following commands in the GDB shell:

(gdb) layout src
(gdb) layout asm
(gdb) layout split

You can know more about debugging rust program commands from here.

If you want to read more content like this?  Subscribe to Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe to Rust Times Newsletter:

rust times

Written by 

Nitin is a Software Consultant, with experience of more than 1.4 years. He works on Rust Programming Language and Embedded Development using Rust. He is also fond of Java Programming & Artificial Intelligence. Apart from that, his hobbies are Watching Netflix, Reading, Singing & Writing.

1 thought on “Do you know how to Debug a Rust Embedded Program?6 min read

Comments are closed.