Skip to content

weak: Pointer.Value() panics for zero-valued receivers #71153

@dfinkel

Description

@dfinkel

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

$ go version
go version go1.24rc1 linux/amd64

Also reproduces with tip.golang.org./play. (see below)

Does this issue reproduce with the latest release?

The weak package is new in go 1.24.

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

go env Output
$ go env
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v3'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/davidf/.cache/go-build'
GODEBUG=''
GOENV='/home/davidf/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2982191925=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOOS='linux'
GOROOT='/usr/lib/go-1.24'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/davidf/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go-1.24/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24rc1'
GOWORK=''
PKG_CONFIG='pkg-config'
uname -sr: Linux 6.1.0-1021-oem
Distributor ID:	Ubuntu
Description:	Ubuntu 23.10
Release:	23.10
Codename:	mantic
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC 2.38-1ubuntu6.3) stable release version 2.38.
gdb --version: GNU gdb (Ubuntu 14.0.50.20230907-0ubuntu1) 14.0.50.20230907-git

What did you do?

I called Value() on a zero-valued weak.Pointer

Simple repro:

package main

import (
	"fmt"
	"weak"
)

func main() {
	var k weak.Pointer[string]
	fmt.Println(k.Value())
}

https://go.dev/play/p/8StbfbJSHuw?v=gotip

Same for calling weak.Make[...](nil): https://go.dev/play/p/J5sbsM-Xe3R?v=gotip

What did you expect to see?

Per the documentation on weak.Pointer, weak.Pointer.Value() should return nil, so the above repro should print nil.

This relevant doc-comment paragraph currently reads:

Calling Make with a nil pointer returns a weak pointer whose Pointer.Value always returns nil. The zero value of a Pointer behaves as if it was created by passing nil to Make and compares equal with such pointers.

What did you see instead?

I received a segfault/panic within the runtime.

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x461fa5]

goroutine 1 gp=0xc000002380 m=0 mp=0x55f440 [running]:
runtime.throw({0x4bb47b?, 0x7f9424c1f108?})
        /usr/lib/go-1.24/src/runtime/panic.go:1099 +0x48 fp=0xc0000a0e80 sp=0xc0000a0e50 pc=0x462c68
runtime.sigpanic()
        /usr/lib/go-1.24/src/runtime/signal_unix.go:909 +0x3c9 fp=0xc0000a0ee0 sp=0xc0000a0e80 pc=0x464169
internal/runtime/atomic.(*Uintptr).Load(...)
        /usr/lib/go-1.24/src/internal/runtime/atomic/types.go:359
weak.runtime_makeStrongFromWeak(0x0)
        /usr/lib/go-1.24/src/runtime/mheap.go:2122 +0x65 fp=0xc0000a0f08 sp=0xc0000a0ee0 pc=0x461fa5
weak.Pointer[...].Value(...)
        /usr/lib/go-1.24/src/weak/pointer.go:81
main.main()
        /tmp/tmp.hEgWnfCcbg/main.go:10 +0x15 fp=0xc0000a0f50 sp=0xc0000a0f08 pc=0x491595
runtime.main()
        /usr/lib/go-1.24/src/runtime/proc.go:283 +0x28b fp=0xc0000a0fe0 sp=0xc0000a0f50 pc=0x433d0b
runtime.goexit({})
        /usr/lib/go-1.24/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0000a0fe8 sp=0xc0000a0fe0 pc=0x468741

It appears that the panic is happening on this Load:
https://cs.opensource.google/go/go/+/master:src/runtime/mheap.go;l=2122;drc=a76cc5a4ecb004616404cac5bb756da293818469

It seems like there should be a nil check at the top of internal_weak_runtime_makeStrongFromWeak before converting u to an *atomic.Uintptr.

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.release-blocker

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions