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

text/tabwriter: index out of range error during concurrent writes #8162

Closed
gopherbot opened this issue Jun 7, 2014 · 2 comments
Closed

text/tabwriter: index out of range error during concurrent writes #8162

gopherbot opened this issue Jun 7, 2014 · 2 comments

Comments

@gopherbot
Copy link

by bcwaldon:

What does 'go version' print?

go version go1.2.1 darwin/amd64

What steps reproduce the problem?

```
package main

import (
        "fmt"
        "os"
        "text/tabwriter"
)

func main() {
        writer := new(tabwriter.Writer)
        writer.Init(os.Stdout, 0, 8, 1, '\t', 0)

        count := 100000

        start := make(chan bool)
        done := make(chan bool, count)

        write := func(msg string) {
                <-start
                fmt.Fprintln(writer, msg)
                done <- true
        }

        for i := 0; i < count; i++ {
                go write("foo")
        }

        close(start)

        for i := 0; i < count; i++ {
                <-done
        }
}
```

What happened?

panic: runtime error: index out of range [recovered]
        panic: interface conversion: interface is runtime.errorCString, not tabwriter.osError [recovered]
        panic: interface conversion: interface is *runtime.TypeAssertionError, not tabwriter.osError

goroutine 33040 [running]:
runtime.panic(0xa64a0, 0x210266080)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/runtime/panic.c:266 +0xb6
text/tabwriter.handlePanic(0x2220732ee0)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:439 +0x4e
runtime.panic(0xa64a0, 0x210266040)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/runtime/panic.c:248 +0x106
text/tabwriter.handlePanic(0x2220732df0)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:439 +0x4e
runtime.panic(0xa6180, 0x18fed7)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/runtime/panic.c:248 +0x106
text/tabwriter.(*Writer).writeLines(0x210269000, 0x0, 0x0, 0x5, 0x3)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:262 +0x5b3
text/tabwriter.(*Writer).format(0x210269000, 0x0, 0x0, 0x5, 0x5)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:370 +0x307
text/tabwriter.(*Writer).Flush(0x210269000, 0x0, 0x0)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:462 +0xce
text/tabwriter.(*Writer).Write(0x210269000, 0x210222068, 0x4, 0x6, 0x4, ...)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/text/tabwriter/tabwriter.go:497 +0x3e9
fmt.Fprintln(0x2239f51640, 0x210269000, 0x2220732f60, 0x1, 0x1, ...)
        /usr/local/Cellar/go/1.2.1/libexec/src/pkg/fmt/print.go:287 +0xa3
main.func·001(0xbcfc0, 0x3)
        /private/tmp/tabwriter.go:20 +0x11a
created by main.main
        /private/tmp/tabwriter.go:25 +0x19d


What should have happened instead?

No panic.

Please provide any additional information below.

This panic is not encountered every time I run the script.
@gopherbot
Copy link
Author

Comment 1 by bcwaldon:

It was pointed out to me that text/tabwriter is probably not threadsafe. If that is
true, working around this issue is as simple as serializing access to the
tabwriter.Writer object.

@davecheney
Copy link
Contributor

Comment 2:

The race detector confirms that text/tabwriter is not threadsafe because it writes
directly to a bytes.Buffer which is not threadsafe.
==================
WARNING: DATA RACE
Write by goroutine 4778:
  bytes.(*Buffer).Write()
      /Users/dfc/go/src/pkg/bytes/buffer.go:126 +0x3f
  text/tabwriter.(*Writer).append()
      /Users/dfc/go/src/pkg/text/tabwriter/tabwriter.go:375 +0x62
  text/tabwriter.(*Writer).Write()
      /Users/dfc/go/src/pkg/text/tabwriter/tabwriter.go:488 +0x1db
  fmt.Fprintln()
      /Users/dfc/go/src/pkg/fmt/print.go:255 +0xae
  main.func·001()
      /Users/dfc/src/issue.go:20 +0x177
Previous write by goroutine 4777:
  bytes.(*Buffer).Truncate()
      /Users/dfc/go/src/pkg/bytes/buffer.go:62 +0x3a
  bytes.(*Buffer).Reset()
      /Users/dfc/go/src/pkg/bytes/buffer.go:75 +0x3d
  text/tabwriter.(*Writer).reset()
      /Users/dfc/go/src/pkg/text/tabwriter/tabwriter.go:99 +0x52
  text/tabwriter.(*Writer).Flush()
      /Users/dfc/go/src/pkg/text/tabwriter/tabwriter.go:468 +0x14d
  text/tabwriter.(*Writer).Write()
      /Users/dfc/go/src/pkg/text/tabwriter/tabwriter.go:501 +0x4cb
  fmt.Fprintln()
      /Users/dfc/go/src/pkg/fmt/print.go:255 +0xae
  main.func·001()
      /Users/dfc/src/issue.go:20 +0x177
Goroutine 4778 (running) created at:
  main.main()
      /Users/dfc/src/issue.go:25 +0x255
Goroutine 4777 (finished) created at:
  main.main()
      /Users/dfc/src/issue.go:25 +0x255
==================

Status changed to Retracted.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants