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

panic: bytes.Buffer: truncation out of range #169

Open
rickzter opened this issue Oct 7, 2017 · 5 comments
Open

panic: bytes.Buffer: truncation out of range #169

rickzter opened this issue Oct 7, 2017 · 5 comments

Comments

@rickzter
Copy link

rickzter commented Oct 7, 2017

When using I/O pipes, specifically, os.Pipe(), while reading the stdout and stderr data, termbox suddenly panics by throwing a "bytes.Buffer: truncation out of range".

Here's the stack trace:
<<
panic: bytes.Buffer: truncation out of range

goroutine 1 [running]:
panic(0x657da0, 0xc82012a840)
/usr/lib/go-1.6/src/runtime/panic.go:481 +0x3e6
bytes.(*Buffer).Truncate(0xa3d3c0, 0x0)
/usr/lib/go-1.6/src/bytes/buffer.go:71 +0xbf
bytes.(*Buffer).WriteTo(0xa3d3c0, 0x7f5bb03504f8, 0xc820092028, 0x90b, 0x0, 0x0)
/usr/lib/go-1.6/src/bytes/buffer.go:225 +0x1af
io.copyBuffer(0x7f5bb03504f8, 0xc820092028, 0x7f5bb0350520, 0xa3d3c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.6/src/io/io.go:370 +0xd0
io.Copy(0x7f5bb03504f8, 0xc820092028, 0x7f5bb0350520, 0xa3d3c0, 0xa3d3c0, 0x0, 0x0)
/usr/lib/go-1.6/src/io/io.go:350 +0x64
github.com/nsf/termbox-go.flush(0x0, 0x0)
/home/rickzter/Dev/go/src/github.com/nsf/termbox-go/termbox.go:234 +0x92
github.com/nsf/termbox-go.Flush(0x0, 0x0)
/home/rickzter/Dev/go/src/github.com/nsf/termbox-go/api.go:199 +0x224

It appears it originates at termbox.Flush(). My function is calling termbox.Clear and finally termbox.Flush(). Any ideas?

I have also encountered this error when using exec.StdoutPipe() as well. It seems termbox does not play nice with I/O pipes. Any workarounds? My program relies on external process communication and this is a show stopper for my app.

@rickzter
Copy link
Author

rickzter commented Oct 7, 2017

I would also like to mention that it is not always the case, sometimes, termbox will not panic and continue, successfully handling the I/O pipe activity, but if I repeat the process, sometimes multiple times, it will eventually panic. Sometimes on the first try.

@rickzter
Copy link
Author

rickzter commented Oct 8, 2017

I am calling termbox.Flush through my function inside a goroutine and using a bufio scanner.

@nsf
Copy link
Owner

nsf commented Oct 8, 2017

Seems like a race condition. If you do termbox.Flush from multiple goroutines. This is now something allowed by the termbox. You can read input (PollEvent) from one goroutine and write output (Flush) in another goroutine. But going beyond that will result in race conditions.

@rickzter
Copy link
Author

rickzter commented Oct 9, 2017

This happens with just running termbox.Flush() from one goroutine. termbox.Flush is being called for each line being read. I can understand if multiple threads were calling termbox.Flush(), but you mentioned it is supported, however, I am able to crash it by only running one go routine alongside the command I am piping to/from.

Here is the code where the problem is originating from:

r, w, _ := os.Pipe()
stdOutOld := os.Stdout
stdErrOld := os.Stderr
os.Stdout = w
os.Stderr = w
go func() {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
ConsoleWriteLine(scanner.Text())
}
termbox.Sync()
}()
_, err := parser.ParseArgs(args)
os.Stdout = stdOutOld
os.Stderr = stdErrOld

ConsoleWriteLine() then calls DrawTerminal():

func (t *Terminal) DrawTerminal() {
termbox.Clear(fg, bg)
termbox.Flush()
}

I am using go-flags parser to parse arguments in my cmd program and basically trying to intercept I/O from this library. It writes to stdout and stderr and redirecting it to my function "ConsoleWriteLine" which stores the information in my output buffer, this function then calls "DrawTerminal()" which clears the termbox buffer and displays it onscreen. Very simple. I am not running multiple goroutines to get this to crash, only this code above with one goroutine running asynchronous to "parser.ParseArgs" to capture I/O.

@rickzter
Copy link
Author

rickzter commented Oct 9, 2017

I was just able to reproduce the error by simply calling termbox.Flush() from a goroutine. It may be related to #113 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants