panic incorrectly attributed to wrong line
stapelberg opened this issue · comments
- What version of Delve are you using (
dlv version
)?
% dlv version
Delve Debugger
Version: 1.22.0
Build: $Id: 61ecdbbe1b574f0dd7d7bad8b6a5d564cce981e9 $
- What version of Go are you using? (
go version
)?
go version go1.21.5 linux/amd64
- What operating system and processor architecture are you using?
linux/amd64
- What did you do?
% go mod init debugme
% cat > debugme.go <<'EOT'
package main
import "os"
func main() {
fi, _ := os.Lstat("/this/path/does/not/exist")
fi.Size()
}
EOT
% go build -gcflags="all=-N -l" debugme.go
% dlv exec ./debugme
(dlv) c
> [unrecovered-panic] runtime.fatalpanic() /usr/lib/go-1.21/src/runtime/panic.go:1188 (hits goroutine(1):1 total:1) (PC: 0x4353e4)
Warning: debugging optimized function
runtime.curg._panic.arg: interface {}(string) "runtime error: invalid memory address or nil pointer dereference"
1183: // fatalpanic implements an unrecoverable panic. It is like fatalthrow, except
1184: // that if msgs != nil, fatalpanic also prints panic messages and decrements
1185: // runningPanicDefers once main is blocked from exiting.
1186: //
1187: //go:nosplit
=>1188: func fatalpanic(msgs *_panic) {
1189: pc := getcallerpc()
1190: sp := getcallersp()
1191: gp := getg()
1192: var docrash bool
1193: // Switch to the system stack to avoid any stack growth, which
(dlv) bt
0 0x00000000004353e4 in runtime.fatalpanic
at /usr/lib/go-1.21/src/runtime/panic.go:1188
1 0x0000000000434bb9 in runtime.gopanic
at /usr/lib/go-1.21/src/runtime/panic.go:1017
2 0x000000000043373e in runtime.panicmem
at /usr/lib/go-1.21/src/runtime/panic.go:261
3 0x000000000044a0a5 in runtime.sigpanic
at /usr/lib/go-1.21/src/runtime/signal_unix.go:861
4 0x00000000004800bf in main.main
at ./debugme.go:6
5 0x0000000000437787 in runtime.main
at /usr/lib/go-1.21/src/runtime/proc.go:267
6 0x0000000000461de1 in runtime.goexit
at /usr/lib/go-1.21/src/runtime/asm_amd64.s:1650
(dlv) frame 4
> [unrecovered-panic] runtime.fatalpanic() /usr/lib/go-1.21/src/runtime/panic.go:1188 (hits goroutine(1):1 total:1) (PC: 0x4353e4)
Warning: debugging optimized function
Frame 4: ./debugme.go:6 (PC: 4800bf)
1: package main
2:
3: import "os"
4:
5: func main() {
=> 6: fi, _ := os.Lstat("/this/path/does/not/exist")
7: fi.Size()
8: }
(dlv)
- What did you expect to see?
frame 4 should have been line 7 (fi.Size()
where fi == nil
)
- What did you see instead?
frame 4 is shown as line 6 (the call to os.Lstat
— no invalid memory access yet)
I see “Warning: debugging optimized function” despite having built with go build -gcflags="all=-N -l" debugme.go
. The go version -m
output confirms that gcflags was set as specified:
% go version -m ./debugme
./debugme: go1.21.5
path command-line-arguments
build -buildmode=exe
build -compiler=gc
build -gcflags="all=-N -l"
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=amd64
build GOOS=linux
build GOAMD64=v1
When stepping through the program, dlv executes line 6 successfully, then encounters a panic when running line 7 (as expected), but in the backtrace of that panic, it says the panic was raised from line 6 (incorrectly): https://gist.github.com/stapelberg/8a752b5363bf5329aff446779e267636