Closed saethlin closed 1 month ago
Merely moving the constant initializations to after the prologue won't fix the stepping issue. We either need the ability to control which DILocations are treated as breakpoint locations by LLVM (a behavior which is currently entirely implicit and that cannot be controlled in the IR) or we would need to initialize constants at their point of use.
@khuey I am very much a debugging/debuginfo/debugger newbie. If you have an amendment or an complete replacement for the issue wording or title (since I don't think you have permission to just modify this issue) please don't hesitate to open a new issue or tell me how to fix the wording above.
I agree that what you're describing sounds a lot more like the root cause of this and other debuginfo weirdness I saw in the test suite.
I don't have a simple suggestion on how to modify this issue because there are at least 3 potential user-visible issues here and they may all have different solutions:
let x = 42;
is optimized down to a single store to a stack slot and that store is moved to the top of the function like it is today it's either going to appear out of line in stepping or it's not going to appear in stepping at all.@rustbot claim
I ran into this as part of https://github.com/rust-lang/rust/pull/128913
Compile this example program extracted from
tests/debuginfo/function-arg-initialization.rs
with
rustc test.rs -g
then load it into gdb withgdb test
and behold:The bug here is that a breakpoint set inside a function can land on an instruction before the function prelude.
As far as I can tell, this is only possible with single-use-consts. You can get the right codegen in current rustc by setting
-Zmir-enable-passes=-SingleUseConsts
. But I think blaming that MIR pass would be mistake because that MIR pass is just a reimplementation of the same concept that used to be calledConstDebugInfo
.Naive attempts to bisect this using the breakpoint method above will all land on https://github.com/rust-lang/rust/pull/107404. But I think that is a wrong bisection, because that PR just fixed an existing MIR pass so that we produce the right span information in our debuginfo.
I think the root cause or the PR that first introduced the bug is https://github.com/rust-lang/rust/pull/73210. You can see in this godbolt demo that rustc 1.50.0 is the version where we start initializing
x
before the function prelude: https://godbolt.org/z/r5W3M4sG9. It's likely that nobody noticed or appreciated how codegen has changed because the debuginfo test for this scenario had been disabled.This problem also afflicts
tests/debuginfo/macro-stepping.rs
, because its strange combination of single-use-consts on the same line as function calls makes stepping through the function hit all those lines before the prelude when the consts are initialized, then again when the functions are called.