diff --git a/_fixtures/cat.go b/_fixtures/cat.go new file mode 100644 index 00000000..eb4e91f4 --- /dev/null +++ b/_fixtures/cat.go @@ -0,0 +1,15 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +func main() { + s := bufio.NewScanner(os.Stdin) + for s.Scan() { + fmt.Printf("read %q\n", s.Text()) + } + os.Stdout.Close() +} diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index f5e1dbfd..52ab06b5 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -296,6 +296,38 @@ func TestChildProcessExitWhenNoDebugInfo(t *testing.T) { } } +// TestRedirect verifies that redirecting stdin works +func TestRedirect(t *testing.T) { + const listenAddr = "127.0.0.1:40573" + + dlvbin, tmpdir := getDlvBin(t) + defer os.RemoveAll(tmpdir) + + catfixture := filepath.Join(protest.FindFixturesDir(), "cat.go") + cmd := exec.Command(dlvbin, "debug", "--headless", "--continue", "--accept-multiclient", "--listen", listenAddr, "-r", catfixture, catfixture) + stdout, err := cmd.StdoutPipe() + assertNoError(err, t, "stderr pipe") + defer stdout.Close() + + assertNoError(cmd.Start(), t, "start headless instance") + + scan := bufio.NewScanner(stdout) + // wait for the debugger to start + for scan.Scan() { + t.Log(scan.Text()) + if scan.Text() == "read \"}\"" { + break + } + } + + // and detach from and kill the headless instance + client := rpc2.NewClient(listenAddr) + if err := client.Detach(true); err != nil { + t.Fatalf("error detaching from headless instance: %v", err) + } + cmd.Wait() +} + func checkAutogenDoc(t *testing.T, filename, gencommand string, generated []byte) { saved := slurpFile(t, filepath.Join(projectRoot(), filename)) diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 843e0a30..872dd9b0 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -349,20 +349,13 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [ foreground := flags&proc.LaunchForeground != 0 - if foreground { - // Disable foregrounding if we can't open /dev/tty or debugserver will - // crash. See issue #1215. - if !isatty.IsTerminal(os.Stdin.Fd()) { - foreground = false - } - } - var ( isDebugserver bool listener net.Listener port string process *exec.Cmd err error + hasRedirects bool ) if debugserverExecutable := getDebugServerAbsolutePath(); debugserverExecutable != "" { @@ -382,18 +375,15 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [ for i := range redirects { if redirects[i] != "" { found[i] = true + hasRedirects = true args = append(args, fmt.Sprintf("--%s-path", names[i]), redirects[i]) } } - if foreground { - if !found[0] && !found[1] && !found[2] { - args = append(args, "--stdio-path", "/dev/tty") - } else { - for i := range found { - if !found[i] { - args = append(args, fmt.Sprintf("--%s-path", names[i]), "/dev/tty") - } + if foreground || hasRedirects { + for i := range found { + if !found[i] { + args = append(args, fmt.Sprintf("--%s-path", names[i]), "/dev/"+names[i]) } } } @@ -423,19 +413,23 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [ process = commandLogger("lldb-server", args...) } - if logflags.LLDBServerOutput() || logflags.GdbWire() || foreground { + if logflags.LLDBServerOutput() || logflags.GdbWire() || foreground || hasRedirects { process.Stdout = os.Stdout process.Stderr = os.Stderr } - if foreground { - foregroundSignalsIgnore() + if foreground || hasRedirects { + if isatty.IsTerminal(os.Stdin.Fd()) { + foregroundSignalsIgnore() + } process.Stdin = os.Stdin } if wd != "" { process.Dir = wd } - process.SysProcAttr = sysProcAttr(foreground) + if isatty.IsTerminal(os.Stdin.Fd()) { + process.SysProcAttr = sysProcAttr(foreground) + } if runtime.GOOS == "darwin" { process.Env = proc.DisableAsyncPreemptEnv()