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

bytes: Buffer crashes in long run #47424

Closed
umtwo opened this issue Jul 27, 2021 · 6 comments
Closed

bytes: Buffer crashes in long run #47424

umtwo opened this issue Jul 27, 2021 · 6 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@umtwo
Copy link

umtwo commented Jul 27, 2021

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

$ go version
go version go1.16.3 

Does this issue reproduce with the latest release?

yes

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

linux/amd64

What did you do?

I used bytes.Buffer package for network operations data buffering in a multi-threaded server.
The flow is very simple as writing to the buffer in any socket read, then read the needed amount if the frame is completed.
The write and read process is protected by Mutex. So no thread conflicts there.

What did you expect to see?

normal operation as a buffer

What did you see instead?

Some times it causes panic while in grow function mostly after a long run.
The trace is as bellow:

panic: runtime error: slice bounds out of range [1230:1228]

goroutine 54 [running]:
bytes.(*Buffer).grow(0xc0001e14a0, 0x52, 0x52)
        /usr/lib/go/src/bytes/buffer.go:137 +0x2b8
bytes.(*Buffer).Write(0xc0001e14a0, 0xc00068b5c0, 0x52, 0x52, 0x52, 0xc00068b5c0, 0x52)
        /usr/lib/go/src/bytes/buffer.go:172 +0xd0

@randall77
Copy link
Contributor

I'm not sure how this could happen. It should always be the case that b.off <= len(b).
Can you run your program with -race?

Without a reproducer we can run, it's going to be hard for us to debug this.

@mvdan
Copy link
Member

mvdan commented Jul 28, 2021

This does look like a data race. I'd encourage you to use one of the forums at https://golang.org/wiki/Questions to get help first.

@mvdan mvdan added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jul 28, 2021
@seankhliao seankhliao changed the title bytes.Buffer crashes in long run bytes: Buffer crashes in long run Jul 28, 2021
@umtwo
Copy link
Author

umtwo commented Jul 28, 2021

I will try to provide more info using race detector, but the way I'm accessing the buffer is like this

type SafeBuffer struct {
	buf    bytes.Buffer
	locker sync.Mutex
}

func (f *SafeBuffer) write(data []byte) {
	f.locker.Lock()
	defer f.locker.Unlock()
	
	f.buf.Write(data)
}

func (f *SafeBuffer) read(len int) []byte {
	f.locker.Lock()
	defer f.locker.Unlock()
	
    if f.buf.Len() >= len {
        return f.buf.Next(len)
    }
    
    return make([]byte, 0)
}

@peterbourgon
Copy link

@umtwo You need to copy the slice returned by Next to a new slice if you intend for your read method to be used concurrently.

@umtwo
Copy link
Author

umtwo commented Aug 19, 2021

@peterbourgon It seems reasonable, I will give it a try. Thanks for the advice

@seankhliao
Copy link
Member

Given no further information, I think this can be closed for now

@golang golang locked and limited conversation to collaborators Feb 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

6 participants