Skip to content

Instantly share code, notes, and snippets.

@ianferguson
Last active July 25, 2022 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ianferguson/ddd03a1c49971ea9d6eca89a283ca499 to your computer and use it in GitHub Desktop.
Save ianferguson/ddd03a1c49971ea9d6eca89a283ca499 to your computer and use it in GitHub Desktop.
golang/go #52086 reproduction
package main
import (
"bytes"
"context"
"fmt"
"net"
"os"
"os/exec"
"time"
)
// This reproduces the process hang described in https://github.com/golang/go/issues/52086 around once every 1200 executions
// I was seemingly able to reproduce the issue more frequently before removing several channels and time based selects, but
// this code is simpler and still triggers the issue fast enough when compiled and then executed inside a for loop on a shell
// using something like the following fish shell snippet:
// go build .; for i in (seq 1 100000); echo "Iteration $i"; ./repro-52086; end;
//
// Note: __CF_USER_TEXT_ENCODING must be set in the environment for this to reproduce ths issue
// ex. `set -x __CF_USER_TEXT_ENCODING "$uidInHex:0x0:0x0"` where uid in hex is your OS X user id encoded as a `0x000` format hex value
// If you are using iTerm 2 or Alacritty as your terminal this is likely already set,
// if you are using Apple Terminal, it likely is not set by default and
// you will need to set it yourself in order to reproduce the process hang
func main() {
// removing the tcp dial altogether or taking it out of the goroutine causes the issue not to reproduce
go func() {
var d net.Dialer
conn, err := d.DialContext(context.Background(), "tcp", "google.com:443")
if err == nil {
defer conn.Close()
} else {
fmt.Printf("error dial: %v", err)
}
}()
result, err := execCmd()
if err != nil {
fmt.Printf("error exec: %v", err)
os.Exit(1)
}
fmt.Printf("exec returned: %v", result)
}
func execCmd() (string, error) {
cmd := exec.Command("echo", time.Now().String())
cmd.Env = []string{}
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("%q: %w", stderr.String(), err)
}
return stdout.String(), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment