go icon indicating copy to clipboard operation
go copied to clipboard

cmd/nm: running nm on object from different version can crash

Open ianlancetaylor opened this issue 1 year ago • 2 comments

Go version

tip

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/iant/.cache/go-build'
GOENV='/home/iant/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/iant/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/iant/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org'
GOROOT='/home/iant/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/iant/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='devel go1.24-bae2e968e2 Mon Sep 30 22:04:40 2024 +0000'
GODEBUG=''
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/iant/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/iant/go/src/go.mod'
GOWORK=''
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-build1550637861=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Where go is current go tip (version go1.24-bae2e968e2) and ~/go1.23/bin/go is go 1.23 (version 1.23.2):

> cat foo.go
package p

func F() any {
	return struct{ p *error}{nil}
}
> go build -o foo.a foo.go
> ~/go1.23/bin/go tool nm foo.a
panic: runtime error: index out of range [255] with length 255

goroutine 1 [running]:
cmd/internal/goobj.BuiltinName(...)
	cmd/internal/goobj/builtin.go:22
cmd/internal/objfile.(*goobjFile).symbols.func2({0x5502a0?, 0x0?})
	cmd/internal/objfile/goobj.go:143 +0x35a
cmd/internal/objfile.(*goobjFile).symbols(0xc0000aa380?)
	cmd/internal/objfile/goobj.go:199 +0xdb0
cmd/internal/objfile.(*Entry).Symbols(0x7ffdf24635a2?)
	cmd/internal/objfile/objfile.go:130 +0x1c
main.nm({0x7ffdf24635a2, 0x5})
	cmd/nm/nm.go:120 +0x1d1
main.main()
	cmd/nm/nm.go:92 +0x2b1

What did you see happen?

Running go1.23 tool nm on an object created by go tip crashed.

What did you expect to see?

I expected to see an error, or ordinary nm output. I did not expect to see a crash.

Since making nm forward compatible seems infeasible, we should change it so that if run on a newer object version it reports an error and exits, rather than crashing.

The object file format already has a magic number that supports this (cmd/internal/goobj.Magic). That magic number is normally changed when the object file format changes. In this case what happened is that the list of builtin names changed. That is part of the object file format, because the index into the builtin name slice is stored in the file format (when the symbol PkgIdx is goobj.PkgIdxBuiltin, the symbol SymIdx is an index into goobj.builtins).

Perhaps we should make cmd/internal/goobj/mkbuiltin.go automatically update the magic number. Or at least print a message saying that the magic number should be updated. Or perhaps we need some different mechanism, like a hash of the builtin names.

CC @golang/compiler

ianlancetaylor avatar Oct 17 '24 22:10 ianlancetaylor

Yeah, we should update the magic number. And it is a good idea to have mkbuiltin.go automatically updates it.

cherrymui avatar Oct 18 '24 00:10 cherrymui

Change https://go.dev/cl/627417 mentions this issue: cmd/internal/goobj: make mkbuiltin.go automatically update Magic const

gopherbot avatar Nov 13 '24 17:11 gopherbot