Open aarzilli opened 1 year ago
CC @golang/compiler.
@dr2chase assigned to you in triage since we want your input but feel free to unassign.
I think this "fixed itself" which is not happy-making. A more permanent fix would be, when assigning line numbers in -N
compilation, to take note of assignments that should have happened earlier and be sure that they are actually completed to memory. I'd like to leave this open but bump it to the next release, since that fix is actually a little complicated.
In case it helps, here is another case extracted from this stackoverflow question :
1 package main
2
3 func main() {
4 a := f(1)
5 b := 1
6
7 c := a < b
8 _ = c
9 }
10
11 func f(i int) int {
12 if i > 0 {
13 return i
14 }
15 return -i
16 }
And here is the output of a delve debug session:
(dlv) l
> main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x4608de)
2:
3: func main() {
4: a := f(1)
5: b := 1
6:
=> 7: c := a < b
8: _ = c
9: }
10:
11: func f(i int) int {
12: if i > 0 {
(dlv) disass
TEXT main.main(SB) /home/zeke/src/temp/76380802/main.go
main.go:3 0x4608c0 493b6610 cmp rsp, qword ptr [r14+0x10]
main.go:3 0x4608c4 7639 jbe 0x4608ff
main.go:3 0x4608c6 4883ec28 sub rsp, 0x28
main.go:3 0x4608ca 48896c2420 mov qword ptr [rsp+0x20], rbp
main.go:3 0x4608cf 488d6c2420 lea rbp, ptr [rsp+0x20]
main.go:4 0x4608d4 b801000000 mov eax, 0x1
main.go:4 0x4608d9 e842000000 call $main.f
=> main.go:7 0x4608de* 4883f801 cmp rax, 0x1
main.go:4 0x4608e2 4889442418 mov qword ptr [rsp+0x18], rax
main.go:5 0x4608e7 48c744241001000000 mov qword ptr [rsp+0x10], 0x1
main.go:7 0x4608f0 0f9c44240f setl byte ptr [rsp+0xf]
main.go:9 0x4608f5 488b6c2420 mov rbp, qword ptr [rsp+0x20]
main.go:9 0x4608fa 4883c428 add rsp, 0x28
main.go:9 0x4608fe c3 ret
main.go:3 0x4608ff 90 nop
main.go:3 0x460900 e83bccffff call $runtime.morestack_noctxt
main.go:3 0x460905 ebb9 jmp $main.main
(dlv) locals
a = 824633745824
b = 824633843808
Another example, this one on arm64:
package main
import "fmt"
func main() {
SimpleMethodWithArgument(0)
}
//go:noinline
func SimpleMethodWithArgument(i int) {
a := 5
y := 10
x := a + y + i // Breakpoint here
fmt.Printf("a: %v, y: %v\n", a, y)
_ = x
return
}
SimpleMethodWithArguments compiles to:
test.go:10 | S | 0x4977c0 | 4c8d6424e8 | LEAQ -0x18(SP), R12 |
---|---|---|---|---|
test.go:10 | 0x4977c5 | 4d3b6610 | CMPQ 0x10(R14), R12 | |
test.go:10 | 0x4977c9 | 0f8615010000 | JBE 0x4978e4 | |
test.go:10 | 0x4977cf | 55 | PUSHL BP | |
test.go:10 | 0x4977d0 | 4889e5 | MOVQ SP, BP | |
test.go:10 | SP | 0x4977d3 | 4881ec90000000 | SUBQ $0x90, SP |
test.go:10 | 0x4977da | 48898424a0000000 | MOVQ AX, 0xa0(SP) | |
test.go:11 | S | 0x4977e2 | 48c744243805000000 | MOVQ $0x5, 0x38(SP) |
test.go:12 | S | 0x4977eb | 48c74424280a000000 | MOVQ $0xa, 0x28(SP) |
test.go:13 | S | 0x4977f4 | 488d480f | LEAQ 0xf(AX), CX |
test.go:13 | 0x4977f8 | 48894c2430 | MOVQ CX, 0x30(SP) | |
test.go:14 | S | 0x4977fd | 440f117c2470 | MOVUPS X15, 0x70(SP) |
at 0x4977d3, the first statement, the stack variables are not yet initialized.
Given the following code:
Compiled with `-gcflags='all=-N -l', main.cul function compiles into:
and the variable
id
hasDW_OP_fbreg -0x18
has its location, however at instruction 0x49c8ea, which is the instruction picked for a breakpoint on line:8
, the variable is stored on register rcx, not in its stack location (where it gets moved only later at instruction 0x49c8ed). Originally reported as https://github.com/go-delve/delve/issues/3290.cc @dr2chase.