Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: WinDbg fails to unwind the Go stack #57404

Closed
qmuntal opened this issue Dec 20, 2022 · 4 comments
Closed

runtime: WinDbg fails to unwind the Go stack #57404

qmuntal opened this issue Dec 20, 2022 · 4 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging OS-Windows
Milestone

Comments

@qmuntal
Copy link
Contributor

qmuntal commented Dec 20, 2022

What version of Go are you using (go version)?

$ go version
go version go1.19.1 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\qmuntaldiaz\AppData\Local\go-build
set GOENV=C:\Users\qmuntaldiaz\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\qmuntaldiaz\go\pkg\mod
set GONOPROXY=github.com/microsoft/*
set GONOSUMDB=github.com/microsoft/*
set GOOS=windows
set GOPATH=C:\Users\qmuntaldiaz\go
set GOPRIVATE=github.com/microsoft/*
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Users\qmuntaldiaz\code\golang-go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Users\qmuntaldiaz\code\golang-go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=devel go1.20-62de58c567 Fri Dec 16 08:50:12 2022 +0100
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\qmuntaldiaz\code\golang-go\src\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\QMUNTA~1\AppData\Local\Temp\go-build4030085144=/tmp/go-build -gno-record-gcc-switches

What did you do?

Debug a Go binary using WinDbg, break at the first instruction of main() and advance step by step.

Synthetic sample:

package main

func main() {
  a()
}

//go:noinline
func a() int {
  return b(0)
}

//go:noinline
func b(i int) int {
  i++
  return i
}

What did you expect to see?

WinDbg is capable of unwind the stack at any PC.

What did you see instead?

The call stack contains is more or less in good shape at the first instruction of main prologue:

Legend:

  • 0x5c7e0: address on main()
  • 0x31a17: address on runtime.main()
  • 0x5c82a: address on a()

image

The call stack contain garbage data after the first instruction that grows the stack pointer inside main() prologue.

image

The call stack is lost after the first instruction that grows the stack pointer inside a() prologue:

image

@qmuntal
Copy link
Contributor Author

qmuntal commented Dec 20, 2022

WinDbg uses RtlVirtualUnwind to unwind the stack, and that function needs SEH unwinding information in the PE binary to correctly display the call stack. Go binaries do not currently contain this information.

See #57302 for more context.

@dr2chase
Copy link
Contributor

I think you intend that this be your bug, feel free to turn that off if I was wrong.

One thing to think about is how to automate testing for some of this; we've tried various things over the years and none of them was entirely satisfactory. The tests that attempted to mimic the experience of a user actually stepping through code were too flaky; probably the Delve API would have been a better approach.

@dr2chase dr2chase added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 20, 2022
@qmuntal
Copy link
Contributor Author

qmuntal commented Dec 20, 2022

I think you intend that this be your bug, feel free to turn that off if I was wrong.

Yep.

One thing to think about is how to automate testing for some of this; we've tried various things over the years and none of them was entirely satisfactory. The tests that attempted to mimic the experience of a user actually stepping through code were too flaky; probably the Delve API would have been a better approach.

Good point. Testing the WinDbg integration will be hard, even if using its interactive command line version, cdb. On the other hand, testing that RtlVirtualUnwind correctly unwinds the stack would be fairly easy, as it can be automated without launching a third-party software. I hope that by making sure RtlVirtualUnwind works we will already fix many integration issues across the board.

@seankhliao seankhliao changed the title WinDbg fails to unwind the Go stack runtime: WinDbg fails to unwind the Go stack Jan 20, 2023
@seankhliao seankhliao added this to the Unplanned milestone Jan 20, 2023
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 20, 2023
@qmuntal
Copy link
Contributor Author

qmuntal commented Jun 7, 2023

SEH stack unwinding has been implemented on windows/amd64, and I can confirm that WinDbg can correctly unwind the Go stack thanks to that. SEH support for windows/arm64 is still not there, the effort is tracked in #57302.

@qmuntal qmuntal closed this as completed Jun 7, 2023
@qmuntal qmuntal removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 7, 2023
@qmuntal qmuntal modified the milestones: Unplanned, Go1.21 Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging OS-Windows
Projects
None yet
Development

No branches or pull requests

4 participants