rust-embedded / discovery

Discover the world of microcontrollers through Rust!
https://docs.rust-embedded.org/discovery/
Apache License 2.0
1.49k stars 515 forks source link

[Chapter 5.3] compiled code seems to be optimized #560

Open Dueesberch opened 9 months ago

Dueesberch commented 9 months ago

I try to debug the led roulette example. When I follow the step by step instructions it goes from let x = 42 to loop{} disassemble the code gives me

(gdb) disassemble /m
Dump of assembler code for function _ZN12led_roulette18__cortex_m_rt_main17h6f63a1cfdbf5915cE:
8   fn main() -> ! {
   0x080001ea <+0>: sub sp, #8
   0x080001ec <+2>: movs    r0, #42 @ 0x2a

9       let _y;
=> 0x080001ee <+4>: str r0, [sp, #0]

10      let x = 42;
   0x080001f0 <+6>: str r0, [sp, #4]

11      _y = x;
12  
13      // infinite loop; just so we don't leave this stack frame
14      loop {}
   0x080001f2 <+8>: b.n 0x80001f4 <led_roulette::__cortex_m_rt_main+10>
   0x080001f4 <+10>:    b.n 0x80001f4 <led_roulette::__cortex_m_rt_main+10>

End of assembler dump.

No assembler instruction after _y = x;

cargo readobj --target thumbv7em-none-eabihf --bin led-roulette -- --file-header
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
warning: the following packages contain code that will be rejected by a future version of Rust: stm32f3xx-hal v0.7.0
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x8000195
  Start of program headers:          52 (bytes into file)
  Start of section headers:          766656 (bytes into file)
  Flags:                             0x5000400
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           40 (bytes)
  Number of section headers:         22
  Section header string table index: 20

shows unoptimized + debuginfo

If I run print _y after let _y; I already get $1 = 42

How to get really unoptimized code?

skoocda commented 7 months ago

I observed this behavior as well. In my case, the assembler code varied slightly but led to the same effect

(gdb) disassemble /m
Dump of assembler code for function _ZN12led_roulette18__cortex_m_rt_main17h327bbe3f14bd160dE:
8       fn main() -> ! {
   0x080001ea <+0>:     sub     sp, #8
   0x080001ec <+2>:     movs    r0, #42 @ 0x2a

9           let _y;
10          let x = 42;
=> 0x080001ee <+4>:     str     r0, [sp, #0]
   0x080001f0 <+6>:     str     r0, [sp, #4]

The register is initialized with the value 42 (0x2a) and then the variables are initialized to that value, leading to the inspection sequence:

(gdb) stepi      
halted: PC: 0x080001ec
0x080001ec      8       fn main() -> ! {

(gdb) info locals
No locals.

(gdb) stepi      
halted: PC: 0x080001ee
10          let x = 42;

(gdb) info locals
x = 42
_y = 42

I also tried building and running with inline-threshold=0 and opt-level=0 but that didn't change the assembly code.