@@ -20,34 +20,55 @@ Continuing.
20
20
21
21
Breakpoint 1, led_roulette::__cortex_m_rt_main_trampoline () at src/05-led-roulette/src/main.rs:7
22
22
7 #[entry]
23
-
24
- (gdb) step
25
- led_roulette::__cortex_m_rt_main () at src/05-led-roulette/src/main.rs:10
26
- 10 let x = 42;
27
23
```
28
24
29
25
Breakpoints can be used to stop the normal flow of a program. The ` continue ` command will let the
30
26
program run freely * until* it reaches a breakpoint. In this case, until it reaches ` #[entry] `
31
- which is a trampoline to to the main function and where ` break main ` set the breakpoint.
27
+ which is a trampoline to the main function and where ` break main ` sets the breakpoint.
32
28
33
- Note that GDB output says "Breakpoint 1". Remember that our processor can only use six of these
34
- breakpoints so it's a good idea to pay attention to these messages.
29
+ > ** Note** that GDB output says "Breakpoint 1". Remember that our processor can only use six of these
30
+ > breakpoints so it's a good idea to pay attention to these messages.
35
31
32
+ OK. Since we are stopped at ` #[entry] ` and using the ` disassemble /m ` we see the code
33
+ for entry, which is a trampoline to main. What that means it sets up the stack and then
34
+ invokes a subroutine call to the ` main ` function using an ARM branch and link instruction, ` bl ` .
35
+ ```
36
+ (gdb) disassemble /m
37
+ Dump of assembler code for function main:
38
+ 8 #[entry]
39
+ 0x080001ec <+0>: push {r7, lr}
40
+ 0x080001ee <+2>: mov r7, sp
41
+ => 0x080001f0 <+4>: bl 0x80001f6 <hello_world::__cortex_m_rt_main>
42
+ 0x080001f4 <+8>: udf #254 ; 0xfe
36
43
37
- OK. Since we are stopped at ` #[entry] ` . We can advance the program statement by statement using
38
- the ` step ` command. So let's use that twice times to reach the ` _y = x ` statement. Once you've typed ` step `
39
- once you can just hit enter to run it again, but below we type step twice.
44
+ End of assembler dump.
45
+ ```
40
46
47
+ Next we need to issue a ` step ` gdb command which will advance the program statement
48
+ by statement stepping into functions/procedures. So after this first ` step ` command we're
49
+ inside ` main ` and are positioned at the first executable ` rust ` statement, line 10, but it is
50
+ ** not** executed:
41
51
```
42
52
(gdb) step
43
53
led_roulette::__cortex_m_rt_main () at src/05-led-roulette/src/main.rs:10
44
54
10 let x = 42;
55
+ ```
56
+
57
+ Next we'll issue a second ` step ` which executes line 10 and stops at
58
+ line ` 11 _y = x; ` , again line 11 is ** not** executed.
59
+
60
+ > ** Note** we could have pressed enter at the second ` <gdb> ` prompt and
61
+ > it would have reissued the previous statement, ` step ` , but for clarity in this tutorial
62
+ > we'll generally retype the command.
63
+
64
+ ```
45
65
(gdb) step
46
66
11 _y = x;
47
67
```
48
68
49
- If you are not using the TUI mode, on each ` step ` call GDB will print back the current statement
50
- along with its line number.
69
+ As you can see, in this mode, on each ` step ` command GDB will print the current statement along
70
+ along with its line number. As you'll see later in the TUI mode you'll not the see the statement
71
+ in the command area.
51
72
52
73
We are now "on" the ` _y = x ` statement; that statement hasn't been executed yet. This means that ` x `
53
74
is initialized but ` _y ` is not. Let's inspect those stack/local variables using the ` print ` command:
@@ -63,13 +84,13 @@ $3 = 536870912
63
84
$4 = (*mut i32) 0x20009fe4
64
85
```
65
86
66
- As expected, ` x ` contains the value ` 42 ` . ` _y ` , however, contains the value ` 536870912 ` (?). Because
67
- ` _y ` has not been initialized yet, it contains some garbage value.
87
+ As expected, ` x ` contains the value ` 42 ` . ` _y ` , however, contains the value ` 536870912 ` (?). This
88
+ is because ` _y ` has not been initialized yet, it contains some garbage value.
68
89
69
90
The command ` print &x ` prints the address of the variable ` x ` . The interesting bit here is that GDB
70
- output shows the type of the reference: ` *mut i32 ` , a mutable pointer to an ` i32 ` value. Another interesting
71
- thing is that the addresses of ` x ` and ` _y ` are very close to each other: their addresses are just
72
- ` 4 ` bytes apart.
91
+ output shows the type of the reference: ` *mut i32 ` , a mutable pointer to an ` i32 ` value. Another
92
+ interesting thing is that the addresses of ` x ` and ` _y ` are very close to each other: their
93
+ addresses are just ` 4 ` bytes apart.
73
94
74
95
Instead of printing the local variables one by one, you can also use the ` info locals ` command:
75
96
@@ -97,9 +118,9 @@ If we use `step` again on top of the `loop {}` statement, we'll get stuck becaus
97
118
never pass that statement.
98
119
99
120
> ** NOTE** If you used the ` step ` or any other command by mistake and GDB gets stuck, you can get
100
- it unstuck by hitting ` Ctrl+C ` .
121
+ > it unstuck by hitting ` Ctrl+C ` .
101
122
102
- You can also use the ` disassemble /m ` command to disassemble the program around the
123
+ As introduced above the ` disassemble /m ` command can be used to disassemble the program around the
103
124
line you are currently at. You might also want to ` set print asm-demangle on `
104
125
so the names are demangled, this only needs to be done once a debug session. Later
105
126
this and other commands will be placed in an initialization file which will simplify
@@ -131,11 +152,11 @@ End of assembler dump.
131
152
132
153
See the fat arrow ` => ` on the left side? It shows the instruction the processor will execute next.
133
154
134
- As mentioned above if you were to execute the ` step ` command GDB gets stuck because it
155
+ Also, as mentioned above if you were to execute the ` step ` command GDB gets stuck because it
135
156
is executing a branch instruction to itself and never gets past it. So you need to use
136
- ` Ctrl+C ` . But you can use the ` stepi ` GDB command, which steps one instruction, and GDB will print
137
- the address ** and** line number of the statement the processor will execute next and
138
- it won't get stuck.
157
+ ` Ctrl+C ` to regain control. An alternative is to use the ` stepi ` GDB command, which steps
158
+ one asm instruction, and GDB will print the address ** and** line number of the statement
159
+ the processor will execute next and it won't get stuck.
139
160
140
161
```
141
162
(gdb) stepi
@@ -154,11 +175,13 @@ Unable to match requested speed 1000 kHz, using 950 kHz
154
175
adapter speed: 950 kHz
155
176
target halted due to debug-request, current mode: Thread
156
177
xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000
178
+
157
179
(gdb) continue
158
180
Continuing.
159
181
160
182
Breakpoint 1, led_roulette::__cortex_m_rt_main_trampoline () at src/05-led-roulette/src/main.rs:7
161
183
7 #[entry]
184
+
162
185
(gdb) disassemble /m
163
186
Dump of assembler code for function main:
164
187
7 #[entry]
@@ -170,11 +193,11 @@ Dump of assembler code for function main:
170
193
End of assembler dump.
171
194
```
172
195
173
- We are now back at the beginning of ` main ` !
196
+ We are now back at the beginning of ` #[entry] ` !
174
197
175
- ` monitor reset halt ` will reset the microcontroller and stop it right at the program entry point .
176
- The following ` continue ` command will let the program run freely until it reaches the ` main `
177
- function that has a breakpoint on it .
198
+ ` monitor reset halt ` will reset the microcontroller and stop it right at the beginning of the program .
199
+ The ` continue ` command will then let the program run freely until it reaches a breakpoint, in
200
+ this case it is the breakpoint at ` #[entry] ` .
178
201
179
202
This combo is handy when you, by mistake, skipped over a part of the program that you were
180
203
interested in inspecting. You can easily roll back the state of your program back to its very
0 commit comments