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

cmd/compile: dev.typeparams: struct with generic parameter triggers 0xb01dfacedebac1e panic on macos #47272

Closed
mccolljr opened this issue Jul 18, 2021 · 6 comments
Assignees
Milestone

Comments

@mccolljr
Copy link

@mccolljr mccolljr commented Jul 18, 2021

Sorry, I'm not exactly sure how to categorize this because the panic happens at runtime but the issue seems to be the result of something funky that happened during compilation:

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

$ go version
go version devel go1.18-df778e6fd9 Sat Jul 17 01:52:18 2021 +0000 darwin/amd64

Does this issue reproduce with the latest release?

N/A

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

Running on: macOS Big Sur 11.4 with 2.6 GHz 6-Core Intel Core i7 and 16 GB 2667 MHz DDR4

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jmccollum/Library/Caches/go-build"
GOENV="/Users/jmccollum/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/jmccollum/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/jmccollum/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/jmccollum/go/src/github.com/golang/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/jmccollum/go/src/github.com/golang/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="devel go1.18-df778e6fd9 Sat Jul 17 01:52:18 2021 +0000"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/jmccollum/go/src/local/other/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/0d/ncmx73fn4s1_n9bz83jdl0lh0000gn/T/go-build4256324592=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Ran this code with go run -gcflags="-G=3" .:

package main

import (
	"errors"
	"fmt"
)

type Option[T any] struct {
	ok  bool
	val T
}

func (o Option[T]) String() string {
	if o.ok {
		return fmt.Sprintf("Some(%v)", o.val)
	}
	return "None"
}

func Some[T any](val T) Option[T] { return Option[T]{ok: true, val: val} }
func None[T any]() Option[T]      { return Option[T]{ok: false} }

type Result[T, E any] struct {
	ok  bool
	val T
	err E
}

func (r Result[T, E]) String() string {
	if r.ok {
		return fmt.Sprintf("Ok(%v)", r.val)
	}
	return fmt.Sprintf("Err(%v)", r.err)
}

func Ok[T, E any](val T) Result[T, E]  { return Result[T, E]{ok: true, val: val} }
func Err[T, E any](err E) Result[T, E] { return Result[T, E]{ok: false, err: err} }

func main() {
	a := Some[int](1)
	b := None[int]()
	fmt.Println(a, b)

	x := Ok[int, error](1)
	y := Err[int, error](errors.New("test"))
	fmt.Println(x, y)
	// fmt.Println(x)
	_, _, _, _ = a, b, x, y
}

What did you expect to see?

$ go run -gcflags="-G=3" .
Some(1) None
Ok(1) Err(test)

What did you see instead?

$ go run -gcflags="-G=3" .
Some(1) None unexpected fault address 0xb01dfacedebac1e fatal error: fault [signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x106eee5]

goroutine 1 [running]:
runtime.throw({0x10a2e1e, 0x401})
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/panic.go:1003 +0x71 fp=0xc000072608 sp=0xc0000725d8 pc=0x102eb31
runtime.sigpanic()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/signal_unix.go:743 +0x2f6 fp=0xc000072658 sp=0xc000072608 pc=0x10425f6
reflect.(*rtype).Kind(...)
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/type.go:820
reflect.unpackEface(...)
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/value.go:150
reflect.Value.Elem({0x1096460, 0xc000010250, 0x726c0})
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/value.go:1154 +0xc5 fp=0xc000072698 sp=0xc000072658 pc=0x106eee5
fmt.(*pp).printValue(0xc000078b60, {0x1096460, 0xc000010250, 0x113e6c0}, 0x76, 0x0)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:810 +0x50a fp=0xc000072880 sp=0xc000072698 pc=0x108764a
fmt.(*pp).printArg(0xc000078b60, {0x1096460, 0xc000010250}, 0x76)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:712 +0x74c fp=0xc000072920 sp=0xc000072880 pc=0x10870ac
fmt.(*pp).doPrintf(0xc000078b60, {0x10a30db, 0x7}, {0xc000072aa0, 0x5, 0x7600000005})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:1026 +0x288 fp=0xc000072a18 sp=0xc000072920 pc=0x10898a8
fmt.Sprintf({0x10a30db, 0x7}, {0xc000072aa0, 0x1, 0x1})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:219 +0x59 fp=0xc000072a70 sp=0xc000072a18 pc=0x1083f79
main..inst.Result[int,error].String(0x10094f4, {0xe0, 0x102d20a, {0x10c0680, 0xc000010250}})
/Users/jmccollum/go/src/local/other/main.go:112 +0xd1 fp=0xc000072ac0 sp=0xc000072a70 pc=0x108ae11
main.(*Result[int,error]).String(0xc000062040)
:1 +0x45 fp=0xc000072af8 sp=0xc000072ac0 pc=0x108b065
fmt.(*pp).handleMethods(0xc000078c30, 0x11a7108)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:626 +0x322 fp=0xc000072d48 sp=0xc000072af8 pc=0x1086422
fmt.(*pp).printArg(0xc000078c30, {0x109b580, 0xc000062040}, 0x76)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:709 +0x693 fp=0xc000072de8 sp=0xc000072d48 pc=0x1086ff3
fmt.(*pp).doPrintln(0xc000078c30, {0xc000072ef0, 0x2, 0x109b580})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:1169 +0x149 fp=0xc000072e58 sp=0xc000072de8 pc=0x108a789
fmt.Fprintln({0x10c06e0, 0xc00000e018}, {0xc000072ef0, 0x2, 0x2})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:264 +0x4f fp=0xc000072ea8 sp=0xc000072e58 pc=0x108404f
fmt.Println(...)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:274
main.main()
/Users/jmccollum/go/src/local/other/main.go:125 +0x210 fp=0xc000072f80 sp=0xc000072ea8 pc=0x108abf0
runtime.main()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/proc.go:255 +0x227 fp=0xc000072fe0 sp=0xc000072f80 pc=0x10311a7
runtime.goexit()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc000072fe8 sp=0xc000072fe0 pc=0x105a321
exit status 2

Apparently related to 0xb01dfacedebac1e

Notes:

  1. Replacing the line fmt.Println(x, y) with fmt.Println(x) avoids the above fault
  2. Replacing the line y := Err[int, error](errors.New("test")) with y := Err[int, string]("test") avoids the fault

This seems to be related to instantiating the generic Result[T,E any] with an E of error and then trying to use reflection on that value from fmt.Sprintf("Err(%v)", <val of type E>)

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 18, 2021

This runs successfully with unified IR:

$ GOEXPERIMENT=unified go run main.go
Some(1) None
Ok(1) Err(test)

Loading

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 18, 2021

CC @randall77 @danscales @mdempsky

In general it is too early to report bugs against the dev.typeparams branch. The branch is under very active development. Fixes are welcome and useful, bug reports are something of a distraction. I'll let this one stand since you already filed it. Thanks.

Loading

@mccolljr
Copy link
Author

@mccolljr mccolljr commented Jul 19, 2021

Ah sorry, I made a bad assumption based on the fact that gopls has some support for type parameters. I was doing some experimentation and ran into this. I'll hold off on filing anything else related to typeparams

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jul 19, 2021

FWIW, I think the issue reports are still useful. Ideally if we can get them as minimized, standalone test cases (i.e., no imports). It's easy enough now to add regress tests that are known to be currently failing, and then we can fix them as we get to them.

Loading

@thanm thanm added this to the Backlog milestone Jul 21, 2021
@danscales danscales self-assigned this Aug 12, 2021
@danscales danscales removed this from the Backlog milestone Aug 12, 2021
@danscales danscales added this to the Go1.18 milestone Aug 12, 2021
@danscales
Copy link

@danscales danscales commented Aug 13, 2021

Thanks for the issue, and sorry for the delay in triaging. This is a good example. Some of our dictionary code is still missing cases where type args are interfaces. We probably think of this as not so common, but here's a good example where a type arg is 'error'.

I'm working on this, and looking for other bugs related to type args which are interface.

Loading

@danscales
Copy link

@danscales danscales commented Aug 17, 2021

Fixed by b7b790a

Loading

@danscales danscales closed this Aug 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants