-
Notifications
You must be signed in to change notification settings - Fork 18k
strange panic SIGSEGV inside lock_futex.go lock #32448
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
Comments
A few questions-
|
we found a way to reproduce this panics. the problem is in race condition around custom contexts and GC(i suppose). here is the code so you can decide if this problem is valuable package main
import (
"context"
"fmt"
"os"
"runtime"
"time"
)
type Context interface {
context.Context
BaseContext() *Base
}
type Base struct {
context context.Context
}
func (c *Base) Done() <-chan struct{} {
return c.context.Done()
}
func (c *Base) BaseContext() *Base {
return c
}
func (c *Base) Deadline() (deadline time.Time, ok bool) {
return c.context.Deadline()
}
func (c *Base) Err() error {
return c.context.Err()
}
func (c *Base) Value(key interface{}) interface{} {
return c.context.Value(key)
}
func WithValue(parent Context, key, val interface{}) Context {
baseCtx := parent.BaseContext()
return &Base{
context: context.WithValue(baseCtx.context, key, val),
}
}
func WithCancelBase(parent Context) (Context, context.CancelFunc) {
baseCtx := parent.BaseContext()
newNetContext, cancel := context.WithCancel(baseCtx.context)
ret := &Base{
context: newNetContext,
}
return ret, cancel
}
type ACTX struct {
Base
}
func (ctx *ACTX) SetValue(key, value interface{}) {
ctx.Base = *(WithValue(ctx.BaseContext(), key, value).BaseContext())
}
func WithCancel(parent *ACTX) (*ACTX, context.CancelFunc) {
baseCtx := parent.BaseContext()
bwCancelCtx, cancel := WithCancelBase(baseCtx.BaseContext())
return &ACTX{
Base: *(bwCancelCtx.BaseContext()),
}, cancel
}
func newACTX() *ACTX {
return &ACTX{Base{context.Background()}}
}
func test(ctx *ACTX, key, value interface{}) {
ctx.SetValue(key, value)
}
func main() {
for i := 0; i < 1000000; i++ {
ctx := newACTX()
ctx, cancel := WithCancel(ctx)
runtime.GOMAXPROCS(4)
for k := 0; k < 10; k++ {
go func() {
for {
select {
default:
case <-ctx.Done():
return
}
}
}()
}
runtime.Gosched()
for j := 0; j < 50; j++ {
test(ctx, j, j)
x := ctx.Value(j)
if intX, ok := x.(int); !ok || intX != j {
fmt.Printf("Unexpected value: %v", x)
os.Exit(0)
}
}
cancel()
}
} |
Yes, I can fix this with a mutex, but I don't understand what is the GC issue here. Can you expand more on that ? What exactly are you seeing ? I believe that should be orthogonal to the race issue we have here. |
ok, i tried with GOGC=off and it still panics. so the problem is only about data race? |
Yes, if you have a race in your program, it will crash regardless of whether GC is enabled or not. |
We know what's the problem, so i close the issue. Thank you. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
i tried only 1.12.1
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
background:
i have a big backend app which is on golang v1.9
i switched golang version on 1.12.1 and deployed this app on production
after switching on 1.12.1 i started to catch very rare panics
whats in code:
i create new WithCancel context (using an old golang.org/x/net/context)
and then i make several goroutines to run mysql queries in parallel
What did you expect to see?
i expect no panic here like it was in 1.9
What did you see instead?
after switching to 1.12.1 the panic sometime happens inside golang stdlib
here is the stack trace of the running goroutine:
i cant reproduce this panic myself. it only panics on production with high rpm.
i took a look at golang stdlib and i dont understand how
&c.lock
might benil
inruntime.sellock()
so it panics onlock_futex.go:55
The text was updated successfully, but these errors were encountered: