-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
What version of Go are you using (go version)?
tip (60ad3c4)
Does this issue reproduce with the latest release?
Unsure. It doesn't immediately reproduce with Go 1.19, but based on the code I think it might be possible.
What operating system and processor architecture are you using (go env)?
Building for linux/arm.
What did you do?
package p
import "log"
import "net"
import "net/http"
import "sync"
type httpServer struct {
l net.Listener
}
func (srv httpServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
panic("XXX")
}
var errLogger *log.Logger
func F(l net.Listener) [3]*int {
var wg sync.WaitGroup
var x [3]*int // use some stack
srv := http.Server{
Handler: httpServer{l: l},
ErrorLog: errLogger,
}
wg.Add(1)
go func() {
srv.Serve(l)
wg.Done()
}()
return x
}
Build this code for ARM
$ GOARCH=arm GOOS=linux go build s.go.
What did you expect to see?
Build successfully.
What did you see instead?
ICE.
$ GOARCH=arm GOOS=linux go-tmp build s.go
# command-line-arguments
<autogenerated>:1: internal compiler error: typebits.Set: invalid initial alignment: type http.Server has alignment 8, but offset is 28
goroutine 9 [running]:
runtime/debug.Stack()
/Users/cherryyz/src/go-tmp/src/runtime/debug/stack.go:24 +0x65
cmd/compile/internal/base.FatalfAt({0x14?, 0x0?}, {0x1997dd3, 0x53}, {0xc000b1f5f8, 0x3, 0x3})
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/base/print.go:227 +0x1d7
cmd/compile/internal/base.Fatalf(...)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/typebits.Set(0xc0008dd880, 0x1c, {0xb1f6a0?, {0xc0005a67d0?, 0xc000680000?, 0x13?}})
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/typebits/typebits.go:18 +0x157
cmd/compile/internal/liveness.(*liveness).pointerMap(0xc000b82140, {0x2?, {0xc0005a67b4?, 0x9?, 0x1?}}, {0xc000450240, 0x7, 0x7?}, {0x5, {0xc0005a67c4, ...}}, ...)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/liveness/plive.go:433 +0x26c
cmd/compile/internal/liveness.(*liveness).emit(0xc000b82140)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/liveness/plive.go:1316 +0x309
cmd/compile/internal/liveness.Compute(0xc000732000, 0xc000502340, 0x19717ed?, 0xb?)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/liveness/plive.go:1372 +0x21d
cmd/compile/internal/ssagen.genssa(0xc000502340, 0xc000644620)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/ssagen/ssa.go:6894 +0xa5
cmd/compile/internal/ssagen.Compile(0xc000732000, 0xc000059f90?)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/ssagen/pgen.go:193 +0x272
cmd/compile/internal/gc.compileFunctions.func4.1(0x0?)
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/gc/compile.go:153 +0x3a
cmd/compile/internal/gc.compileFunctions.func3.1()
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/gc/compile.go:140 +0x4d
created by cmd/compile/internal/gc.compileFunctions.func3
/Users/cherryyz/src/go-tmp/src/cmd/compile/internal/gc/compile.go:138 +0x78
Here, we have a local variable srv of type http.Server, which contains a sync.WaitGroup which in turn contains a atomic.Uint64, which makes it 8-byte aligned even on 32-bit platforms.
The compiler already force variables with alignment larger than the stack alignment (PtrSize) to heap. But here for the composite literal assignment the compiler generates an autotmp
. AS Def tc(1) # s.go:21:6
. . NAME-p.srv esc(h) Class:PAUTO Offset:0 Addrtaken Used http.Server tc(1) # s.go:21:2
. . NAME-p..autotmp_6 esc(N) Class:PAUTO Offset:0 AutoTemp OnStack Used http.Server tc(1) # s.go:21:20
That autotmp lives on stack, and doesn't have 8-byte alignment. This triggers an assertion when emitting the stack maps https://cs.opensource.google/go/go/+/master:src/cmd/compile/internal/typebits/typebits.go;l=17
I think it is probably okay to have an under-aligned autotmp on stack. The only purpose for the autotmp is to copy the value to the LHS, and the copying code we generate (at least currently) doesn't care the alignment beyond stack alignment. So maybe we can relax the check to allow under-aligned values on stack? (It would be good to check that it is only used for copying and doesn't need the alignment beyond PtrSize, but I'm not sure how to.)
Not sure if there is a better fix. Not using such autotmp would need much more work.
We could align the offset of the autotmp to 8 bytes, which would satisfy the check. But it is just faking. The actual address at run time may not necessarily be 8-byte aligned.