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

fmt: printing a map with unsafe.Pointer keys crashes #42622

Closed
hanlins opened this issue Nov 16, 2020 · 2 comments
Closed

fmt: printing a map with unsafe.Pointer keys crashes #42622

hanlins opened this issue Nov 16, 2020 · 2 comments
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@hanlins
Copy link
Contributor

hanlins commented Nov 16, 2020

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

$ go version
1.14

Does this issue reproduce with the latest release?

Yes

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

darwin/amd64, should be consistent for all platforms.

go env Output
$ go env

What did you do?

This is the code for reproduce:

package main

import (
	"fmt"
	"reflect"
)

func main() {
	str1 := "str1"
	str2 := "str2"
	m := map[reflect.Value]struct{}{}
	m[reflect.ValueOf(&str1)] = struct{}{}
	fmt.Printf("#1: map: %+v\n", m)
	m[reflect.ValueOf(&str2)] = struct{}{}
	// panic here
	fmt.Printf("#2: map: %+v\n", m)
}

Here's the output:

➜  node go run main.go
#1: map: map[<*string Value>:{}]
panic: bad type in compare: unsafe.Pointer

goroutine 1 [running]:
internal/fmtsort.compare(0x10acf20, 0xc00000c148, 0xba, 0x10acf20, 0xc00000c128, 0xba, 0xba)
	/Users/hanlins/.gvm/gos/go1.14/src/internal/fmtsort/sort.go:181 +0x13b6
internal/fmtsort.compare(0x10cdb00, 0xc00000c140, 0x99, 0x10cdb00, 0xc00000c120, 0x99, 0xc000062240)
	/Users/hanlins/.gvm/gos/go1.14/src/internal/fmtsort/sort.go:158 +0xea8
internal/fmtsort.(*SortedMap).Less(0xc000062240, 0x1, 0x0, 0x20)
	/Users/hanlins/.gvm/gos/go1.14/src/internal/fmtsort/sort.go:27 +0x87
sort.insertionSort(0x10eca40, 0xc000062240, 0x0, 0x2)
	/Users/hanlins/.gvm/gos/go1.14/src/sort/sort.go:27 +0xc4
sort.stable(0x10eca40, 0xc000062240, 0x2)
	/Users/hanlins/.gvm/gos/go1.14/src/sort/sort.go:368 +0x86
sort.Stable(0x10eca40, 0xc000062240)
	/Users/hanlins/.gvm/gos/go1.14/src/sort/sort.go:357 +0x53
internal/fmtsort.Sort(0x10b3ea0, 0xc000062180, 0x15, 0x99)
	/Users/hanlins/.gvm/gos/go1.14/src/internal/fmtsort/sort.go:71 +0x434
fmt.(*pp).printValue(0xc000064ea0, 0x10b3ea0, 0xc000062180, 0x15, 0x76, 0x0)
	/Users/hanlins/.gvm/gos/go1.14/src/fmt/print.go:773 +0xcd4
fmt.(*pp).printArg(0xc000064ea0, 0x10b3ea0, 0xc000062180, 0x76)
	/Users/hanlins/.gvm/gos/go1.14/src/fmt/print.go:716 +0x292
fmt.(*pp).doPrintf(0xc000064ea0, 0x10cf10c, 0x9, 0xc00006cf40, 0x1, 0x1)
	/Users/hanlins/.gvm/gos/go1.14/src/fmt/print.go:1030 +0x15a
fmt.Fprintf(0x10ec360, 0xc00000e018, 0x10cf10c, 0x9, 0xc00006cf40, 0x1, 0x1, 0x1d, 0x0, 0x0)
	/Users/hanlins/.gvm/gos/go1.14/src/fmt/print.go:204 +0x72
fmt.Printf(...)
	/Users/hanlins/.gvm/gos/go1.14/src/fmt/print.go:213
main.main()
	/Users/hanlins/test/node/main.go:16 +0x2dc
exit status 2

What did you expect to see?

The behavior for storing values of same type (e.g. reflect.Value) should be consistent. Either it should reject storing reflect.Value during compilation (since it contains unsafe.Pointer that is non-comparable), or it should be able to correctly handle reflect.Value as key.

What did you see instead?

If multiple reflect.Value of same type being stored, it will panic when iterating the map keys (e.g. print the map). It would be nice to make unsafe.Pointer comparable just like uintptr to mitigate the issue.

Similar to #33610

hanlins added a commit to hanlins/go that referenced this issue Nov 16, 2020
@hanlins hanlins changed the title When storing reflect.Value as keys in map, panic iterating the map When storing reflect.Value as keys in map, panic printing the map Nov 16, 2020
@ianlancetaylor ianlancetaylor changed the title When storing reflect.Value as keys in map, panic printing the map fmt: printing a map with unsafe.Pointer keys crashes Nov 16, 2020
@ianlancetaylor
Copy link
Contributor

Thanks. Simpler test case that also crashes at runtime:

package main

import (
	"fmt"
	"unsafe"
)

var v1, v2 int

func main() {
	m := make(map[unsafe.Pointer]bool)
	m[unsafe.Pointer(&v1)] = true
	m[unsafe.Pointer(&v2)] = true
	fmt.Println(m)
	
}

@ianlancetaylor ianlancetaylor added the NeedsFix The path to resolution is known, but the work has not been done. label Nov 16, 2020
@ianlancetaylor ianlancetaylor added this to the Go1.17 milestone Nov 16, 2020
@gopherbot
Copy link

Change https://golang.org/cl/270277 mentions this issue: internal/fmtsort: sort the unsafe pointers in map

hanlins added a commit to hanlins/go that referenced this issue Nov 16, 2020
hanlins added a commit to hanlins/go that referenced this issue Nov 16, 2020
@golang golang locked and limited conversation to collaborators Nov 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants