What version of Go are you using (go version)?
$ go version
go version go1.11.4 linux/amd64
but also devel at c043fc4 (newest as of today)
What did you do?
Take this program:
package main
import "fmt"
var aflag = false
var bflag = false
func testfn() {
if bflag {
if aflag {
g()
}
}
h()
}
func g() {
}
func h() {
fmt.Printf("breakpoint skipped\n")
}
func main() {
testfn()
}
compile with go build -gcflags='-N -l' onajmp.go, then:
$ gdb ./onajmp
...
Reading symbols from ./onajmp...done.
Loading Go Runtime support.
(gdb) b /home/a/temp/onajmp.go:15
Breakpoint 1 at 0x487748: file /home/a/temp/onajmp.go, line 15.
(gdb) r
Starting program: /home/a/temp/onajmp
[New LWP 1180]
[New LWP 1181]
[New LWP 1182]
breakpoint skipped
[LWP 1175 exited]
[LWP 1180 exited]
[LWP 1182 exited]
[Inferior 1 (process 1175) exited normally]
(or use delve+break+continue, exact same thing).
The breakpoint on line 15 (the call to main.h) gets skipped entirely.
Why
onajmp.go:8 | S | 0x487710 | 64488b0c25f8ffffff | MOVQ FS:0xfffffff8, CX
onajmp.go:8 | | 0x487719 | 483b6110 | CMPQ 0x10(CX), SP
onajmp.go:8 | | 0x48771d | 763d | JBE 0x48775c
onajmp.go:8 | SP | 0x48771f | 4883ec08 | SUBQ $0x8, SP
onajmp.go:8 | | 0x487723 | 48892c24 | MOVQ BP, 0(SP)
onajmp.go:8 | | 0x487727 | 488d2c24 | LEAQ 0(SP), BP
onajmp.go:9 | S | 0x48772b | 803db6770e0000 | CMPB $0x0, 0xe77b6(IP)
onajmp.go:9 | | 0x487732 | 7502 | JNE 0x487736
onajmp.go:9 | | 0x487734 | eb24 | JMP 0x48775a
onajmp.go:10 | S | 0x487736 | 803daa770e0000 | CMPB $0x0, 0xe77aa(IP)
onajmp.go:10 | | 0x48773d | 7502 | JNE 0x487741
onajmp.go:10 | | 0x48773f | eb17 | JMP 0x487758
onajmp.go:11 | S | 0x487741 | e82a000000 | CALL main.g(SB)
onajmp.go:11 | | 0x487746 | eb00 | JMP 0x487748
onajmp.go:15 | S | 0x487748 | eb00 | JMP 0x48774a
onajmp.go:15 | | 0x48774a | e831000000 | CALL main.h(SB)
onajmp.go:16 | S | 0x48774f | 488b2c24 | MOVQ 0(SP), BP
onajmp.go:16 | | 0x487753 | 4883c408 | ADDQ $0x8, SP
onajmp.go:16 | | 0x487757 | c3 | RET
onajmp.go:10 | | 0x487758 | ebee | JMP 0x487748
onajmp.go:9 | | 0x48775a | ebee | JMP 0x48774a
onajmp.go:8 | S | 0x48775c | e82f71fcff | CALL runtime.morestack_noctxt(SB)
onajmp.go:8 | | 0x487761 | ebad | JMP main.testfn(SB)
The statement marker for line 15 ends up on instruction 0x487748, a JMP, instead of 0x48774a. But the program reaches that line from another path that jumps directly to 0x48774a. Specifically through: 0x487734 → 0x48775a → 0x48774a.
@gopherbot, please add label Debugging
cc @heschik @dr2chase
What version of Go are you using (
go version)?but also devel at c043fc4 (newest as of today)
What did you do?
Take this program:
compile with
go build -gcflags='-N -l' onajmp.go, then:(or use delve+break+continue, exact same thing).
The breakpoint on line 15 (the call to main.h) gets skipped entirely.
Why
The statement marker for line 15 ends up on instruction 0x487748, a JMP, instead of 0x48774a. But the program reaches that line from another path that jumps directly to 0x48774a. Specifically through: 0x487734 → 0x48775a → 0x48774a.
@gopherbot, please add label Debugging
cc @heschik @dr2chase