Skip to content

os/exec: data race between StdoutPipe and Wait #19685

Closed
@xxorde

Description

@xxorde

Problem

If you are reading from cmd.StdoutPipe() and call cmd.Wait() concurrent you get a race condition.
I needed some time to find this in my code, but once I knew what I was looking for I found the same problem in other codebases, blogposts, ect.

This is really similar to: #9307
I am quite sure I am not the first one to find this, but I could not find a matching issue, please close this if there is one.

Example

Here is a little example.
I did not constructed it, I actually found it in a blog post.

package main

import (
	"bufio"
	"fmt"
	"os"
	"os/exec"
)

func main() {
	cmdName := "echo"
	cmdArgs := []string{"hello", "world"}

	cmd := exec.Command(cmdName, cmdArgs...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
		os.Exit(1)
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("%s\n", scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
		os.Exit(1)
	}

	err = cmd.Wait()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err)
		os.Exit(1)
	}
}

Here you can see it failing on different CI / Go versions: https://github.com/xxorde/race

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

  • 1.6.x
  • 1.7.x
  • 1.8.x
  • master

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

linux, amd64

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions