urfave / cli

A simple, fast, and fun package for building command line apps in Go

Home Page:https://cli.urfave.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple race conditions

dlsniper opened this issue · comments

My urfave/cli version is

v2.25.0 / v3.0.0-alpha2.0.20230307054335-e55fb61e7a9e

Checklist

  • Are you running the latest v2 release? The list of releases is here.
  • Did you check the manual for your release? The v2 manual is here
  • Did you perform a search about this problem? Here's the GitHub guide about searching.

Dependency Management

  • My project is using go modules.

Describe the bug

There are several race conditions happening in both v2 and in v3.

These issues seem to have appeared in versions past v2.19.2.

To reproduce

package main

import (
	"time"

	// "github.com/urfave/cli/v2" // Uncomment if testing against v2
	"github.com/urfave/cli/v3" // Uncomment if testing against v3
)

var demoFlag = &cli.StringFlag{
	Name:    "demo",
	Value:   "demo",
	Usage:   "demo",
	EnvVars: []string{"RACE_DEMO"},
}

var appCommands = []*cli.Command{
	{
		Name:  "race",
		Usage: "Start the demo",
		Flags: []cli.Flag{demoFlag},
		Action: func(c *cli.Context) error {
			return cmd1(c)
		},
	},
}

func cmd1(_ *cli.Context) error {
	time.Sleep(1 * time.Second)
	return nil
}

func newApp() *cli.App {
	app := cli.App{
		Name:            "demo",
		HideHelpCommand: true,
		HideVersion:     true,
		HideHelp:        true,
		Commands:        appCommands,
	}
	return &app
}

func main() {
	go func() {
		startArgs := []string{
			"demo",
			"race",
		}
		err := newApp().Run(startArgs)
		if err != nil {
			panic(err)
		}
	}()

	var err error

	for i := 0; i < 3; i++ {
		startArgs := []string{
			"demo",
			"race",
		}
		err = newApp().Run(startArgs)
		if err == nil {
			return
		}
		time.Sleep(500 * time.Millisecond)
	}
	if err != nil {
		panic(err)
	}
}

Observed behavior

What did you see happen immediately after the reproduction steps
above?

See the races files:

Expected behavior

Run the code above with:

go run -race main.go

Run go version and paste its output here

go version go1.19.5 linux/amd64

Run go env and paste its output here

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/florin/.cache/go-build"
GOENV="/home/florin/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/florin/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/florin/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/florin/go-sdks/go1.19.5"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/florin/go-sdks/go1.19.5/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19.5"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/florin/projects/demo/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4197316836=/tmp/go-build -gno-record-gcc-switches"

Duplicate of #1242

@dlsniper In general this library is NOT intended to be thread safe. For most use cases it isnt required. We dont intend to fix this as there are many other ramifications