Skip to content

runtime: Go 1.27.0: SIGSEGV crash with generic function + pointer type parameter + embedded interface #81089

Description

@gospider001

Go version

go version go1.27.0 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/zhaoxiaoxiao/go/bin'
GOCACHE='/Users/zhaoxiaoxiao/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/zhaoxiaoxiao/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/ck/x440zyk97ss3lvz6vqw506tr0000gn/T/go-build3868367583=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/Users/zhaoxiaoxiao/go/pkg/mod'
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Users/zhaoxiaoxiao/go'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/zhaoxiaoxiao/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.27.0'
PKG_CONFIG='pkg-config'

What did you do?

Minimal reproduction code

package main

import "log"

type Conn interface{ Hello() }
type PoolConn struct{ Conn } // embedded interface
type CustomConn struct{}

func (p CustomConn) Hello() { log.Print("Hello") }

func call[T Conn](c T) { c.Hello() }

func main() {
	// Crash: generic + pointer type parameter + embedded interface
	call[*PoolConn](&PoolConn{Conn: CustomConn{}})
}

Expected behavior

The program should print Hello normally (consistent with the two working variants below).

Actual behavior

The program crashes directly with the following output:

unexpected fault address 0x100011df0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x2 addr=0x100011df0 pc=0x100011df0]

goroutine 1 gp=0xeb2a8761e0 m=0 mp=0x100405660 [running]:
runtime.throw({0x100346741?, 0x1003461bc?})
        /usr/local/go/src/runtime/panic.go:1243 +0x38 fp=0xeb2a916df0 sp=0xeb2a916dc0 pc=0x10032ae58
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:945 +0x20c fp=0xeb2a916e50 sp=0xeb2a916df0 pc=0x10032c18c
main.main()
        /tmp/mini2.go:16 +0x54 fp=0xeb2a916ea0 sp=0xeb2a916e60 pc=0x1003461e4
runtime.main()
        /usr/local/go/src/runtime/proc.go:302 +0x380 fp=0xeb2a916fd0 sp=0xeb2a916ea0 pc=0x1002faea0
runtime.goexit({})
        /usr/local/go/src/runtime/asm_arm64.s:1039 +0x4 fp=0xeb2a916fd0 sp=0xeb2a916fd0 pc=0x100330514
...
exit status 2

Comparison tests

1. Non-generic direct call (works ✅)

func main() {
	var c *PoolConn = &PoolConn{Conn: CustomConn{}}
	c.Hello() // prints: Hello
}

2. Generic + value type parameter (works ✅)

func main() {
	call[PoolConn](PoolConn{Conn: CustomConn{}}) // prints: Hello
}

3. Generic + pointer type parameter (crashes ❌)

func main() {
	call[*PoolConn](&PoolConn{Conn: CustomConn{}}) // SIGSEGV crash
}

Additional findings

  1. go vet reports no warnings — the issue cannot be detected statically.
  2. go run -gcflags=-d=checkptr=2 also fails to detect it and still crashes.
  3. The crash address 0x100011df0 equals pc=0x100011df0, meaning the program jumped to an invalid/unmapped address (a typical bad itab or function pointer issue).
  4. In the original code, if the value-type variant is called first and then the pointer-type variant, the program works — suggesting the bug is related to the order/caching of generic instantiation. It looks like the compiler mishandles the itab of the embedded interface when generating the generic instantiation for *PoolConn.

Original code (real-world scenario)

package main

import (
	"log"
)

type Conn interface{ Hello() }
type Pool[T Conn] struct{}

func (p *Pool[T]) Hello(conn T) { conn.Hello() }

type PoolConn struct{ Conn }
type CustomConn struct{}

func (p CustomConn) Hello() { log.Print("Hello") }

func NewPool[T Conn]() *Pool[T] { return &Pool[T]{} }

func main() {
	// Commenting out this line makes the next line crash; keeping both lines works
	NewPool[PoolConn]().Hello(PoolConn{Conn: CustomConn{}})
	NewPool[*PoolConn]().Hello(&PoolConn{Conn: CustomConn{}})
}

Impact

  • Any code using generic + pointer type parameter + embedded interface may trigger this.
  • The crash is runtime-only and cannot be caught at compile time; go vet doesn't detect it either.
  • This pattern is common in real projects (e.g. a connection pool Pool[T] managing connection objects implementing an interface), so the risk is high.

Suggestions

  • Expect the Go team to confirm this is a compiler/runtime bug (likely an error in handling the embedded interface's method table during generic instantiation).
  • Temporary workaround: use value type parameters, or avoid the combination of pointer type parameters + embedded interfaces in generics.

What did you see happen?

The program should print Hello normally

What did you expect to see?

The program should print Hello normally

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

NeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions