You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Modifying locals potentially broken with recent Rust #236
I'm working through the discovery book and just did the gdb session in this chapter.
What I found is that while info locals properly reports my change to half_period, the behaviour did not change. So I went through calls to the delay_ms methods again and found that the calling parameter is still the original value of 500.
What I am wondering is if this is due to Rust recent changes with respect to constant value optimizations. Could it be that the half_period (which is a primitive type and only read twice and never written) is optimized away? I can imagine that it would be sufficient to write the value somewhere to the binary and let delay_ms access it directly without doing the usual stack-frame handling.
My questions are:
Can you give me hints on how to validate my hypothesis?
Can we (jointly) fix this by modifying the usage or declaration of half_period so that it is really modifiable interactively in gdb?
I guess fixing this would save others from trying out this example and wondering why it does not work.
Reacted by Vincent Olesen, Acácio Centeno, Yerkebulan Tulibergenov, Arbestor Dinggleback, swpease and Tim Phillips
Thanks for looking into assembly and confirming my hypothesis. Your code makes sense but is indeed "strange".
I wondered if one could make the variable volatile as it is also done in the register section of the book.
I found the volatile crate, which could be used for that. Still, a developer would not per-se make this variable volatile, as it actually is not expected to change without doing live-rewrite in the debugger. But that would at least provide similar "changability" while having less contrived code.
Maybe leveraging volatile and explaining the details in a "note"-box would educate the reader and make the example work again.
I believe this is a result of MIR constant propagation, which is done by rustc before it generates LLVM IR and runs LLVM's optimization passes. In recent versions of rustc, MIR constant propagation is enabled by default in debug mode because it reduces compile times. You can disable it using the -Zmir-opt-level=0 rustc flag (requires a nightly build of the Rust toolchain).
Activity
netzdoktor commentedon May 22, 2020
Thanks for looking into assembly and confirming my hypothesis. Your code makes sense but is indeed "strange".
I wondered if one could make the variable volatile as it is also done in the register section of the book.
I found the volatile crate, which could be used for that. Still, a developer would not per-se make this variable volatile, as it actually is not expected to change without doing live-rewrite in the debugger. But that would at least provide similar "changability" while having less contrived code.
Maybe leveraging
volatileand explaining the details in a "note"-box would educate the reader and make the example work again.yerke commentedon Jul 1, 2020
I also just ran into this issue. @wupdiduh thanks for finding a workaround. I had to modify it a bit:
I had to use half_period before changing the value, so the compiler wouldn't optimize it away.
mbrubeck commentedon Nov 29, 2020
From a thread in the Rust forum:
I believe this is a result of MIR constant propagation, which is done by rustc before it generates LLVM IR and runs LLVM's optimization passes. In recent versions of rustc, MIR constant propagation is enabled by default in debug mode because it reduces compile times. You can disable it using the
-Zmir-opt-level=0rustc flag (requires a nightly build of the Rust toolchain).migueloller commentedon Dec 1, 2020
Unfortunately using
-Zmir-opt-leveldoesn't work. I've only been able to get around the optimization by doing what @yerke did.winksaville commentedon Dec 23, 2020
Here are a couple other solutions I came up with.
Cargo.toml to add
volatile = "0.4.2"as a dependency:And the main.rs is now:
Change half_period with: