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/go: windows binaries shouldn't be marked with IMAGE_FILE_DEBUG_STRIPPED #59391

Closed
qmuntal opened this issue Apr 3, 2023 · 1 comment
Closed
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@qmuntal
Copy link
Contributor

qmuntal commented Apr 3, 2023

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

go version go1.20.2 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\***\AppData\Local\go-build
set GOENV=C:\Users\***\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\***\go\pkg\mod
set GONOPROXY
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\***\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Users\***\code\golang-go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Users\***\code\golang-go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20.2
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\***\code\go-lab\go.mod
set GOWORK=C:\Users\***\code\go-lab\go.work
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\***\AppData\Local\Temp\go-build1712504696=/tmp/go-build -gno-record-gcc-switches

Context

The Go linker sets the IMAGE_FILE_DEBUG_STRIPPED PE characteristic for all internal-linked binaries. The PE format docs defines this characteristic as:

Debugging information is removed from the image file.

This definition is misleading, it does not really mean that the debugging information has been completely deleted, but that it has been removed from the PE file and moved into a DBG file.

This other Microsoft doc explains it better:

DBG files have been superseded by PDB files, which are now more commonly used for debugging.

You can use the REBASE.EXE utility to strip debug information from a PE-format executable and store it in a DBG file. The file characteristic field IMAGE_FILE_DEBUG_STRIPPED in the PE file header tells the debugger that Codeview information has been stripped to a separate DBG file.

The Go linker is not creating a DBG file with debugging information, so it should not set the IMAGE_FILE_DEBUG_STRIPPED characteristic, else some tools, such as SymChk, will report a validation error if the corresponding DBG file is not found (see following sections for an example of a symchk execution).

This small PE incompliance has been there since the very beginning without anyone complaining. That's because Go binaries don't contain Windows-native debugging information (CodeView, DBG, PDB, ...), so there is no need to run debugging-related tools on them. My team at Microsoft is trying to improve this situation by generating PDB files from Go binaries so they can be debugged by WinDbg and friends (the tool is not public yet, but we plan to open-source it at some point). In this new context, having the IMAGE_FILE_DEBUG_STRIPPED characteristic is annoying, as debugging tools first try to search for a DBG file instead of going directly to the PDB, possibly reporting an error while doing so.

What did you do?

  1. Build using the following dummy program with

go build -o main.exe .

package main

func main() {
  println("foo")
}
  1. Run SymChk

symchk /v ./main.exe /s .

What did you expect to see?

...
[SYMCHK] [ 0x00000000 - 0x000f0001 ] Checked "C:\Users\***\code\go-lab\cmd\gotest\gotest.exe"

SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 1

What did you see instead?

...
DBGHELP: C:\Users\***\code\go-lab\cmd\gotest\gotest.exe is stripped.  Searching for dbg file
DBGHELP: .\gotest.dbg - file not found
DBGHELP: .\exe\gotest.dbg - path not found
DBGHELP: .\symbols\exe\gotest.dbg - path not found
DBGHELP: C:\Users\***\code\go-lab\cmd\gotest\gotest.dbg - file not found
...
[SYMCHK] [ 0x00000000 - 0x000f0301 ] Checked "C:\Users\***\code\go-lab\cmd\gotest\gotest.exe"
SYMCHK: gotest.exe           FAILED  - Image is split correctly, but gotest.dbg is missing

SYMCHK: FAILED files = 1
SYMCHK: PASSED + IGNORED files = 0

@alexbrainman @golang/windows

@qmuntal qmuntal added OS-Windows compiler/runtime Issues related to the Go compiler and/or runtime. labels Apr 3, 2023
@qmuntal qmuntal self-assigned this Apr 3, 2023
@gopherbot
Copy link

Change https://go.dev/cl/481615 mentions this issue: cmd/link/internal/ld: don't set IMAGE_FILE_DEBUG_STRIPPED on PE binaries

@thanm thanm added the NeedsFix The path to resolution is known, but the work has not been done. label Apr 3, 2023
@mknyszek mknyszek added this to the Go1.21 milestone Apr 5, 2023
@golang golang locked and limited conversation to collaborators Apr 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

No branches or pull requests

4 participants