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

cmd/compile: missing DWARF location lists for local variables in optimized code #67130

Open
andreimatei opened this issue May 1, 2024 · 2 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@andreimatei
Copy link
Contributor

Go version

go1.22.2

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/andrei/.cache/go-build'
GOENV='/home/andrei/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/andrei/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/andrei/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/andrei/sdk/go1.22.2'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/andrei/sdk/go1.22.2/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.2'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/andrei/src/github.com/DataExMachina-dev/demos/rpc-deadlock/server/go.mod'
GOWORK='/home/andrei/src/github.com/DataExMachina-dev/demos/rpc-deadlock/go.work'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2497644278=/tmp/go-build -gno-record-gcc-switches'

What did you do?

A lot of times, debug information for local variables (i.e. location lists) seem to be missing when compiling in optimized mode. When using -gcflags="-N -l", the location information is there. I want to discuss a particular case where optimizations do not seem to be the problem.

What did you see happen?

I believe that it is generally known that location info can be missing. I'd like to use this opportunity to understand why that is / whether there is a big general problem or many small ones and how deep or superficial the issues are. The case that I want to discuss here in particular seems more general then what I find in other issues on the topic (e.g. #60479). An interesting thing is that, as far as I can tell, optimization passes don't seem to be the problem here.

Consider the following function:

func varTest() time.Duration {
	processingStart := time.Now()

	// Simulate a lengthy operation.
	time.Sleep(time.Minute)

	return time.Since(processingStart)
}

processingStart does not get any debug info. The output of GOSSAFUNC seems immediately suspicious to me because, from the very beginning, there is no VarDef node for processingStart (whereas the no-optimizations build does have a VarDef). As I understand it, ssa/debug.go looks for VarDef, so I'm guessing that the missing VarDef mean that this variable never stood a chance to get location lists. Is that correct?

Here is the GOSSAFUNC output for the function, namely the very first column (before insert phis). The processingStart variable is declared on source line 111. Notice that there is no VarDef there, but instead there is a StaticLECall / SelectN.

b1:-
  v1 (?) = InitMem <mem>
  v2 (?) = SP <uintptr>
  v3 (?) = SB <uintptr>
  v4 (?) = LocalAddr <*time.Duration> {~r0} v2 v1
  v5 (?) = Const64 <time.Duration> [0]
  v6 (111) = StaticLECall <time.Time,mem> {AuxCall{time.Now}} v1
  v7 (111) = SelectN <mem> [1] v6
  v8 (111) = SelectN <time.Time> [0] v6 (processingStart[time.Time])
  v9 (?) = Const64 <time.Duration> [60000000000]
  v10 (114) = StaticLECall <mem> {AuxCall{time.Sleep}} [8] v9 v7
  v11 (114) = SelectN <mem> [0] v10
  v12 (116) = StaticLECall <time.Duration,mem> {AuxCall{time.Since}} [24] v8 v11
  v13 (116) = SelectN <mem> [1] v12
  v14 (116) = SelectN <time.Duration> [0] v12
  v15 (116) = MakeResult <time.Duration,mem> v14 v13
Ret v15 (+116)

name processingStart[time.Time]: v8

My hope is that perhaps there's a superficial reason why some variables are quickly disqualified from having location lists.

I'm asking because I'm working on debugging tooling and missing location lists is biting me a lot.

cc @randall77 @dr2chase

What did you expect to see?

Location list for the processingStart variable.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label May 1, 2024
@randall77
Copy link
Contributor

The processingStart variable, which is SSAable, is broken up by the compiler (when in optimized mode) to individual fields. It does not need a VARDEF`` for the whole thing. So yes, the VARDEF` is missing. But there should be some sort of DWARF for its respective fields? They do get spilled to (probably 3 distinct unrelated) stack slots, but the DWARF should describe those somehow, I think.
@thanm

@andreimatei
Copy link
Contributor Author

The reason why I clung to VarDef missing was that in #60479 we saw that the elision of VarDef causes location lists to go missing.
However, this present issue seems different than #60479 because, as I understand it, the regression in #60479 does not apply to pointer-ful types (and time.Time contains a pointer), and also because I've tested the code with go1.19 (before the #60479 regression) and I still don't get location lists.

@cherrymui cherrymui added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 6, 2024
@cherrymui cherrymui added this to the Backlog milestone May 6, 2024
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. FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

6 participants