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

runtime: Invalid "concurrent map writes" after recovered runtime-panic on previous map assign with non-comparable key #19359

Closed
navytux opened this issue Mar 2, 2017 · 2 comments
Milestone

Comments

@navytux
Copy link
Contributor

navytux commented Mar 2, 2017

Please answer these questions before submitting your issue. Thanks!

What did you do?

Please consider the following program:

package main

import "fmt"

// mapSet sets m[key] = value, but returns error when k is of not-appropriate type
func mapSet(m map[interface{}]interface{}, key, value interface{}) (err error) {
        defer func() {
                if r := recover(); r != nil {
                        // XXX it is better to check r.Error() to has "unhashable type ..."
                        err = fmt.Errorf("mapSet: %v", r)
                }
        }()

        m[key] = value
        return nil

}

func main() {
        m := make(map[interface{}]interface{})
        //keyv := []interface{} {"aaa", "hello"}
        keyv := []interface{} {[]int{1, 2, 3}, "hello"}
        v := "world"

        for i, k := range keyv {
                err := mapSet(m, k, v)
                fmt.Printf("step%d: key = %#v -> %v\n", i, k, err)
        }
}

(https://play.golang.org/p/_YPsKUivic)

What did you expect to see?

step0: key = []int{1, 2, 3} -> mapSet: runtime error: hash of unhashable type []int
step1: key = "hello" -> <nil>

What did you see instead?

step0: key = []int{1, 2, 3} -> mapSet: runtime error: hash of unhashable type []int
fatal error: concurrent map writes

goroutine 1 [running]:
runtime.throw(0x4aaf32, 0x15)
        /home/kirr/src/tools/go/go/src/runtime/panic.go:596 +0x95 fp=0xc42003bc60 sp=0xc42003bc40
runtime.mapassign(0x4928e0, 0xc42003be08, 0xc42003bd20, 0x1)
        /home/kirr/src/tools/go/go/src/runtime/hashmap.go:499 +0x688 fp=0xc42003bd00 sp=0xc42003bc60
main.mapSet(0xc42003be08, 0x48d240, 0x4b3120, 0x48d240, 0xc42000e310, 0x0, 0x0)
        /home/kirr/tmp/trashme/mapassign.go:14 +0x9e fp=0xc42003bd40 sp=0xc42003bd00
main.main()
        /home/kirr/tmp/trashme/mapassign.go:26 +0x217 fp=0xc42003bf88 sp=0xc42003bd40
runtime.main()
        /home/kirr/src/tools/go/go/src/runtime/proc.go:185 +0x20a fp=0xc42003bfe0 sp=0xc42003bf88
runtime.goexit()
        /home/kirr/src/tools/go/go/src/runtime/asm_amd64.s:2148 +0x1 fp=0xc42003bfe8 sp=0xc42003bfe0
exit status 2

Does this issue reproduce with the latest release (go1.8)?

yes

System details

go version devel +f072283bce Thu Mar 2 06:08:42 2017 +0000 linux/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/kirr/go"
GORACE=""
GOROOT="/home/kirr/src/tools/go/go"
GOTOOLDIR="/home/kirr/src/tools/go/go/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build846511103=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOROOT/bin/go version: go version devel +f072283bce Thu Mar 2 06:08:42 2017 +0000 linux/amd64
GOROOT/bin/go tool compile -V: compile version devel +f072283bce Thu Mar 2 06:08:42 2017 +0000 X:framepointer
uname -sr: Linux 4.9.0-1-amd64
Distributor ID:	Debian
Description:	Debian GNU/Linux 9.0 (stretch)
Release:	9.0
Codename:	stretch
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Debian GLIBC 2.24-9) stable release version 2.24, by Roland McGrath et al.
gdb --version: GNU gdb (Debian 7.12-6) 7.12.0.20161007-git

The question here is whether map should be still considered usable after access with non-comparable element.

This issue originally came in the context of decoding python pickles and what to use - panics or reflect to detect non-comparable dict keys:

kisielk/og-rek#30 (comment) (and below).

Thanks beforehand,
Kirill

@navytux navytux changed the title runtime: Invalid "concurrent map writes" after recovered runtime-panic on previous map assign with non-comparable type runtime: Invalid "concurrent map writes" after recovered runtime-panic on previous map assign with non-comparable key Mar 2, 2017
@josharian josharian self-assigned this Mar 2, 2017
@josharian josharian added this to the Go1.9 milestone Mar 2, 2017
@gopherbot
Copy link

CL https://golang.org/cl/37665 mentions this issue.

@navytux
Copy link
Contributor Author

navytux commented Mar 2, 2017

Thanks for fixing.

@golang golang locked and limited conversation to collaborators Mar 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants