pkg/proc,service/*: Supports sending output to clients when running programs remotely (#3253)

* wip: Support sending output when remote debug

* wip: Support local output and remote output

* wip: fix stderr and stdout assignment error

* wip: optimize code

* wip: Only if outputMode is "remote" is the redirected console output

* wip: Redirected debugMode output(Not tested on windows)

* wip: support remote debugging output redirection of windows

* wip: real-time write back output

* wip: support for windows

* wip: fix windows remote debug not output

* wip: fix truncated output redirection

* wip: delete printfln

* wip: use debugger.Config to pass redirect(macOS)

* wip: use debugger.Config to pass redirect(linux)

* wip: Change redirect to a concrete type

* wip: s.wg.wait before sending "terminated"

* wip: add proc/redirect test(darwin and linux)

* Merge branch 'master' of github.com:tttoad/delve into feat-console

* wip: Fix test failure on windows

* fix: undefined: proc.Redirects

* fix: compile failure

* wip: Remove useless code

* fix: filename error

* fix: os.file not close

* test: add server_test.redirect

* fix: Remove 'eol' from end of file

* fix: gdbserial: File not closed in file mode.
(in reality, gdbserial will never use file mode)

* feat: Remove "only-remote". Fix spelling mistakes.

* fix: spelling mistakes

* refactor: redirect

* fix: stdout and stderr are not set to default values

* fix: Restore code logic for rr.openRedirects()

* fix: Optimization Code

* fix: utiltest

* fix: execpt out

* fix: Resource release for redirects

* fix: build failure

* fix: clean->clear

* fix: build failure

* fix: test failure

* fix: Optimization Code

* style: remove useless code

* refactor: namedpipe

* refactor: namedpipe, launch ...

* fix: freebsd compile failure

* fix: proc_darwin compile failure

* style:  remove useless code

* feat: add d.config.Stdxx check on debug.Restart

* style: formatting and adding comments

* style: formatting and adding comments

* feat: add d.config.Stdxx check on debug.Restart

* style: namedpipe->redirector

* style: namedPipe->redirector

---------

Co-authored-by: 李翔 <qian.fu2@amh-group.com>
This commit is contained in:
ttoad
2023-07-05 23:39:01 +08:00
committed by GitHub
parent d963eb1057
commit 53998cbb18
20 changed files with 399 additions and 66 deletions

View File

@ -136,8 +136,14 @@ type Config struct {
// ExecuteKind contains the kind of the executed program.
ExecuteKind ExecuteKind
// Redirects specifies redirect rules for stdin, stdout and stderr
Redirects [3]string
// Stdin Redirect file path for stdin
Stdin string
// Redirects specifies redirect rules for stdout
Stdout proc.OutputRedirect
// Redirects specifies redirect rules for stderr
Stderr proc.OutputRedirect
// DisableASLR disables ASLR
DisableASLR bool
@ -259,16 +265,16 @@ func (d *Debugger) Launch(processArgs []string, wd string) (*proc.TargetGroup, e
switch d.config.Backend {
case "native":
return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)
return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Stdin, d.config.Stdout, d.config.Stderr)
case "lldb":
return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects))
return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, [3]string{d.config.Stdin, d.config.Stdout.Path, d.config.Stderr.Path}))
case "rr":
if d.target != nil {
// restart should not call us if the backend is 'rr'
panic("internal error: call to Launch with rr backend and target already exists")
}
run, stop, err := gdbserial.RecordAsync(processArgs, wd, false, d.config.Redirects)
run, stop, err := gdbserial.RecordAsync(processArgs, wd, false, d.config.Stdin, d.config.Stdout, d.config.Stderr)
if err != nil {
return nil, err
}
@ -303,9 +309,9 @@ func (d *Debugger) Launch(processArgs []string, wd string) (*proc.TargetGroup, e
case "default":
if runtime.GOOS == "darwin" {
return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects))
return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, [3]string{d.config.Stdin, d.config.Stdout.Path, d.config.Stderr.Path}))
}
return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)
return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Stdin, d.config.Stdout, d.config.Stderr)
default:
return nil, fmt.Errorf("unknown backend %q", d.config.Backend)
}
@ -472,12 +478,19 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs []
return nil, ErrCanNotRestart
}
if !resetArgs && (d.config.Stdout.File != nil || d.config.Stderr.File != nil) {
return nil, ErrCanNotRestart
}
if err := d.detach(true); err != nil {
return nil, err
}
if resetArgs {
d.processArgs = append([]string{d.processArgs[0]}, newArgs...)
d.config.Redirects = newRedirects
d.config.Stdin = newRedirects[0]
d.config.Stdout = proc.OutputRedirect{Path: newRedirects[1]}
d.config.Stderr = proc.OutputRedirect{Path: newRedirects[2]}
}
var grp *proc.TargetGroup
var err error
@ -501,7 +514,7 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs []
}
if recorded {
run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Redirects)
run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Stdin, d.config.Stdout, d.config.Stderr)
if err2 != nil {
return nil, err2
}