Ah! I apologize... in reducing it to a compact example I didn't notice that I changed the semantics of what the code was doing. You are, of course, right about the cause of the deadlock in this code.
That said, working backward from the self-contained example to my full code clarified the actual issue I'm debugging. It is sufficiently different from what I said here that I will start a new thread if I can't figure it out myself. Thank you! -- Salvatore smile. On Sun, Jun 16, 2024 at 10:35 PM Robert Engels <reng...@ix.netcom.com> wrote: > It hangs because cmd.Run() waits for the process to complete - and with > nothing reading the pipe it will never complete. > > On Jun 16, 2024, at 9:33 PM, Robert Engels <reng...@ix.netcom.com> wrote: > > > It looks like you don’t have anything reading from the pipe so it’s going > to hang. > > On Jun 16, 2024, at 8:54 PM, Salvatore Domenick Desiano < > neard...@gmail.com> wrote: > > > Simpler self-contained example, same result: > > func main() { > > cmdName := "/bin/bash" > cmdArgs := []string{"-c", "while true; do echo step; sleep 1; done"} > > cmdStdoutR, cmdStdoutW := io.Pipe() > cmd := exec.Command(cmdName, cmdArgs...) > cmd.Stdout = cmdStdoutW > if err := cmd.Run(); err != nil { > > fmt.Println(err) > > } > fmt.Println("DONE") > > cmdStdoutR = cmdStdoutR > > } > > For the sake of completeness I'll mention that this runs fine if > cmd.Stdout is not assigned, which points to exec.awaitGoroutines() as being > the culprit. > > FWIW, I have no direct evidence that the pipes aren't being closed on the > SIGKILL. That said, the (exec-internal) goroutines are hung on io.Copy(). I > expect that if the process's output pipe was actually closed the io.Copy() > would return, the goroutine would complete, and the deadlock would not > happen. > > -- Salvatore > smile. > > > On Sun, Jun 16, 2024 at 7:58 PM Salvatore Domenick Desiano < > neard...@gmail.com> wrote: > >> I hope this isn't a red herring but in constructing a self-contained >> example I triggered a deadlock. Perhaps the deadlock is the answer to my >> question or perhaps it is another issue. Either way this code does not seem >> malformed: >> >> func main() { >> >> cmdName := "/bin/bash" >> cmdArgs := []string{ >> >> "-c", >> >> "while true; do echo step; sleep 1; done", >> >> } >> cmdStdinR, cmdStdinW := io.Pipe() >> cmdStdoutR, cmdStdoutW := io.Pipe() >> cmdStderrR, cmdStderrW := io.Pipe() >> ctx, cancelCmd := context.WithCancel(context.Background()) >> cmd := exec.CommandContext(ctx, cmdName, cmdArgs...) >> cmd.Stdin = cmdStdinR >> cmd.Stdout = cmdStdoutW >> cmd.Stderr = cmdStderrW >> >> if err := cmd.Start(); err != nil { >> >> fmt.Println(err) >> >> } >> >> cmdStdinW.Close() >> if err := cmd.Wait(); err != nil { >> >> fmt.Println(err) >> >> } >> >> fmt.Println("DONE") >> >> cancelCmd = cancelCmd >> cmdStdoutR = cmdStdoutR >> cmdStderrR = cmdStderrR >> >> } >> >> If you run this code and SIGKILL the bash process, go flags it as a >> deadlock and panics. FWIW, this also happens if there are goroutines >> monitoring cmdStdoutR and cmdStderrR. >> >> What am I missing? >> >> -- Salvatore >> smile. >> >> >> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/CAEQs7S-Gwuvh8MJ48Nv1Cwd7miHiUX4RdwKjqmeLqMBcWYYgJQ%40mail.gmail.com > <https://groups.google.com/d/msgid/golang-nuts/CAEQs7S-Gwuvh8MJ48Nv1Cwd7miHiUX4RdwKjqmeLqMBcWYYgJQ%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEQs7S-5zCsBDd2fOGcLtAzjHGPE16bLWT750Ru7MuYhhw-bmA%40mail.gmail.com.