Closed
Description
Go version
1.24.0
go env
set AR=ar set CC=gcc set CGO_CFLAGS=-O2 -g set CGO_CPPFLAGS= set CGO_CXXFLAGS=-O2 -g set CGO_ENABLED=1 set CGO_FFLAGS=-O2 -g set CGO_LDFLAGS=-O2 -g set CXX=g++ set GCCGO=gccgo set GO111MODULE= set GOAMD64=v1 set GOARCH=amd64 set GOAUTH=netrc go: stripping unprintable or unescapable characters from %"GOBIN"% set GOBIN=C:\Users\������\Desktop\Go\bin go: stripping unprintable or unescapable characters from %"GOCACHE"% set GOCACHE=C:\Users\������\Desktop\Go\cache set GOCACHEPROG= set GODEBUG= go: stripping unprintable or unescapable characters from %"GOENV"% set GOENV=C:\Users\������\AppData\Roaming\go\env set GOEXE=.exe set GOEXPERIMENT= set GOFIPS140=off set GOFLAGS= go: stripping unprintable or unescapable characters from %"GOGCCFLAGS"% set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\������\AppData\Local\Temp\go-build2224281176=/tmp/go-build -gno-record-gcc-switches set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOINSECURE= go: stripping unprintable or unescapable characters from %"GOMOD"% set GOMOD=C:\Users\������\Desktop\project\gate\go.mod go: stripping unprintable or unescapable characters from %"GOMODCACHE"% set GOMODCACHE=C:\Users\������\Desktop\Go\pkg\mod set GONOPROXY= set GONOSUMDB= set GOOS=windows go: stripping unprintable or unescapable characters from %"GOPATH"% set GOPATH=C:\Users\������\Desktop\Go set GOPRIVATE= set GOPROXY=direct set GOROOT=C:\Program Files\Go set GOSUMDB=off set GOTELEMETRY=local go: stripping unprintable or unescapable characters from %"GOTELEMETRYDIR"% set GOTELEMETRYDIR=C:\Users\������\AppData\Roaming\go\telemetry set GOTMPDIR= set GOTOOLCHAIN=auto set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64 set GOVCS= set GOVERSION=go1.24.0 go: stripping unprintable or unescapable characters from %"GOWORK"% set GOWORK=C:\Users\������\Desktop\project\go.work set PKG_CONFIG=pkg-config
What did you do?
in my project,there has a very strange panic when update from 1.23.6 to 1.24.0
package main
import (
"context"
"fmt"
"io"
"strconv"
"sync/atomic"
"github.com/chenjie199234/Corelib/cerror"
"github.com/chenjie199234/Corelib/container/list"
"github.com/chenjie199234/Corelib/monitor"
)
type Msg struct {
H *MsgHeader
B *MsgBody
WithB bool
}
type MsgBody struct {
Body []byte
Error *cerror.Error
}
type MsgHeader struct {
Callid uint64
Path string
Type int
Deadline int64
Metadata map[string]string
Tracedata map[string]string
Traildata map[string]string
}
type rw struct {
callid uint64
path string
metadata map[string]string
traceddata map[string]string
deadline int64
reader *list.BlockList[*MsgBody]
sender func(context.Context, *Msg) error
status atomic.Int32 //use right 4 bit,the bit from left to right:peer_read_status,peer_send_status,self_read_status,self_send_status
e error
}
func newrw(callid uint64, path string, deadline int64, md, td map[string]string, sender func(context.Context, *Msg) error) *rw {
tmp := &rw{
callid: callid,
path: path,
metadata: md,
traceddata: td,
deadline: deadline,
reader: list.NewBlockList[*MsgBody](),
sender: sender,
}
tmp.status.Store(0b1111)
return tmp
}
func (this *rw) init(body *MsgBody) error {
return this.sender(context.Background(), &Msg{
H: &MsgHeader{
Callid: this.callid,
Path: this.path,
Type: 1,
Deadline: this.deadline,
Metadata: this.metadata,
Tracedata: this.traceddata,
},
B: body,
WithB: body != nil,
})
}
func (this *rw) send(body *MsgBody) error {
if this.status.Load()&0b0001 == 0 {
if this.e != nil {
return this.e
}
return cerror.ErrCanceled
}
if this.status.Load()&0b1000 == 0 {
return io.EOF
}
if e := this.sender(context.Background(), &Msg{
H: &MsgHeader{
Callid: this.callid,
Path: this.path,
Type: 2,
},
B: body,
WithB: body != nil,
}); e != nil {
return e
}
if body.Error != nil {
//if we send error to peer,means we stop send
this.status.And(0b1110)
}
return nil
}
func (this *rw) closesend() error {
if old := this.status.And(0b1110); old&0b0001 == 0 {
return nil
}
return this.sender(context.Background(), &Msg{
H: &MsgHeader{
Callid: this.callid,
Path: this.path,
Type: 3,
},
})
}
func (this *rw) closerecv() error {
if old := this.status.And(0b1101); old&0b0010 == 0 {
return nil
}
this.reader.Close()
return this.sender(context.Background(), &Msg{
H: &MsgHeader{
Callid: this.callid,
Path: this.path,
Type: 4,
},
})
}
func (this *rw) closerecvsend(trail bool, err error) error {
if old := this.status.And(0b1100); old&0b0011 == 0 {
return nil
}
this.e = err
this.reader.Close()
m := &Msg{
H: &MsgHeader{
Callid: this.callid,
Path: this.path,
Type: 5,
},
}
if trail {
m.H.Traildata = map[string]string{"Cpu-Usage": strconv.FormatFloat(monitor.LastUsageCPU, 'g', 10, 64)}
}
return this.sender(context.Background(), m)
}
func (this *rw) recv() ([]byte, error) {
if this.status.Load()&0b0010 == 0 {
if this.e != nil {
return nil, this.e
}
return nil, cerror.ErrCanceled
}
m, e := this.reader.Pop(context.Background())
if e != nil {
if e == list.ErrClosed {
if this.e != nil {
return nil, this.e
}
if this.status.Load()&0b0100 == 0 {
return nil, io.EOF
}
if this.status.Load()&0b0010 == 0 {
return nil, cerror.ErrCanceled
}
return nil, cerror.ErrClosed
} else {
//this is impossible
return nil, cerror.Convert(e)
}
}
//fix interface nil problem
if m.Error == nil || m.Error.Code == 0 {
return m.Body, nil
}
//if we read error from peer,means peer stop send
this.status.And(0b1011)
this.reader.Close()
return m.Body, m.Error
}
func (this *rw) cache(m *MsgBody) error {
_, e := this.reader.Push(m)
if e == list.ErrClosed {
e = cerror.ErrClosed
}
return e
}
func main() {
rw := newrw(101, "/test", 0, nil, nil, func(ctx context.Context, m *Msg) error {
return nil
})
rw.closerecvsend(true, nil)
fmt.Println("finish")
select {}
}
module demo
go 1.23.0
require github.com/chenjie199234/Corelib v0.0.133-0.20250221101755-b7a3a9d25afa
What did you see happen?
same code
works fine in 1.23.6
panic in 1.24.0
What did you expect to see?
works fine