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

maps: maps.Clone reference semantics when cloning a map with large value types #64474

Closed
santegoeds opened this issue Nov 30, 2023 · 7 comments
Closed
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done. release-blocker
Milestone

Comments

@santegoeds
Copy link

santegoeds commented Nov 30, 2023

Go version

go version go1.21.4 linux/amd64

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

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/tdog/.cache/go-build'
GOENV='/home/tdog/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/tdog/.asdf/installs/golang/1.21.4/packages/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/tdog/.asdf/installs/golang/1.21.4/packages'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/tdog/.asdf/installs/golang/1.21.4/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/tdog/.asdf/installs/golang/1.21.4/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/tdog/dev/maps-clone/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-build1194712858=/tmp/go-build -gno-record-gcc-switches'

What did you do?

https://go.dev/play/p/vkz2JOzn6zV

package main

import (
	"fmt"
	"maps"
)

type Value struct {
	Val     int
	padding [100]int
}

func main() {
	const key = "key"

	m := make(map[string]Value)

	m[key] = Value{Val: 1}

	c := maps.Clone(m)

	v := m[key]
	v.Val = 2
	m[key] = v

	fmt.Println(m[key].Val, c[key].Val)
}

Possibly related to https://go-review.googlesource.com/c/go/+/471400

What did you expect to see?

2 1

What did you see instead?

2 2
@bcmills bcmills added compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Nov 30, 2023
@bcmills
Copy link
Contributor

bcmills commented Nov 30, 2023

@gopherbot, please backport to Go 1.21. This appears to cause subtle aliasing bugs in cloned maps.

@gopherbot
Copy link

Backport issue(s) opened: #64475 (for 1.21).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@findleyr
Copy link
Contributor

(I made a minor correction to the original report, changing the expectation to 2 1 (from 1 2)).

@mauri870
Copy link
Member

I can confirm this behavior changed after CL 471400 moved the Clone implementation to the runtime.

@randall77
Copy link
Contributor

@cuiweixie

@mauri870
Copy link
Member

mauri870 commented Nov 30, 2023

The bug triggers this branch of mapclone2 https://go.googlesource.com/go/+/refs/heads/master/src/runtime/map.go#1512

	if src.B == 0 {
		dst.buckets = newobject(t.Bucket)
		dst.count = src.count
		typedmemmove(t.Bucket, dst.buckets, src.buckets)
		return dst
	}

@dmitshur dmitshur added this to the Go1.22 milestone Nov 30, 2023
@gopherbot
Copy link

Change https://go.dev/cl/546515 mentions this issue: maps: fix aliasing problems with Clone

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Dec 1, 2023
ezz-no pushed a commit to ezz-no/go-ezzno that referenced this issue Feb 18, 2024
Make sure to alloc+copy large keys and values instead of aliasing them,
when they might be updated by a future assignment.

Fixes golang#64474

Change-Id: Ie2226a81cf3897e4e2ee24472f2966d397ace53f
Reviewed-on: https://go-review.googlesource.com/c/go/+/546515
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
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. NeedsFix The path to resolution is known, but the work has not been done. release-blocker
Projects
Development

No branches or pull requests

8 participants