提交 cb658772 编写于 作者: B Brian de Alwis 提交者: Derek Parker

cmd/dlv: add --continue to continue process on launch/attach (#1585)

* Add --continue to continue process on launch/attach

* Add small test of --continue

* regenerate usage docs

* minor cleanup

* Use similar approach to `trace` and connect and detach using a client instance

* back out previous attempt

* regen usage doc

* fix up continue test

* fix TestContinue to properly test --continue

* back out unnecessary changes

* update faq
上级 f67239f3
......@@ -28,14 +28,10 @@ And then connect to it from outside the container:
dlv connect :4040
```
The program will not start executing until you connect to Delve and send the `continue` command. If you want the program to start immediately you can do that by:
1. Passing the `--accept-multiclient` option to the headless instance of delve: `dlv exec --headless --listen :4040 --accept-multiclient /path/to/executable`
2. Using the following script:
The program will not start executing until you connect to Delve and send the `continue` command. If you want the program to start immediately you can do that by passing the `--continue` and `--accept-multiclient` options to Delve:
```
#!/bin/bash
while true; do sleep 1; dlv connect :4040 --init <(echo quit -c) && exit; done
dlv exec --headless --continue --listen :4040 --accept-multiclient /path/to/executable
```
Note that the connection to Delve is unauthenticated and will allow arbitrary remote code execution: *do not do this in production*.
......@@ -19,6 +19,7 @@ dlv debug [package]
### Options
```
--continue Continue the debugged process on start.
--output string Output path for the binary. (default "./__debug_bin")
```
......
......@@ -17,6 +17,12 @@ or later, -gcflags="-N -l" on earlier versions of Go.
dlv exec <path/to/binary>
```
### Options
```
--continue Continue the debugged process on start.
```
### Options inherited from parent commands
```
......
......@@ -33,6 +33,8 @@ var (
LogDest string
// Headless is whether to run without terminal.
Headless bool
// ContinueOnStart is whether to continue the process on startup
ContinueOnStart bool
// APIVersion is the requested API version while running headless
APIVersion int
// AcceptMulti allows multiple clients to connect to the same server
......@@ -172,6 +174,7 @@ session.`,
Run: debugCmd,
}
debugCommand.Flags().String("output", "./__debug_bin", "Output path for the binary.")
debugCommand.Flags().BoolVar(&ContinueOnStart, "continue", false, "Continue the debugged process on start.")
RootCommand.AddCommand(debugCommand)
// 'exec' subcommand.
......@@ -195,6 +198,7 @@ or later, -gcflags="-N -l" on earlier versions of Go.`,
os.Exit(execute(0, args, conf, "", executingExistingFile))
},
}
execCommand.Flags().BoolVar(&ContinueOnStart, "continue", false, "Continue the debugged process on start.")
RootCommand.AddCommand(execCommand)
// Deprecated 'run' subcommand.
......@@ -561,7 +565,17 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile
defer logflags.Close()
if Headless && (InitFile != "") {
fmt.Fprint(os.Stderr, "Warning: init file ignored\n")
fmt.Fprint(os.Stderr, "Warning: init file ignored with --headless\n")
}
if ContinueOnStart {
if !Headless {
fmt.Fprint(os.Stderr, "Error: --continue only works with --headless; use an init file\n")
return 1
}
if !AcceptMulti {
fmt.Fprint(os.Stderr, "Error: --continue requires --accept-multiclient\n")
return 1
}
}
if !Headless && AcceptMulti {
......@@ -633,6 +647,11 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile
var status int
if Headless {
if ContinueOnStart {
var client *rpc2.RPCClient
client = rpc2.NewClient(listener.Addr().String())
client.Disconnect(true) // true = continue after disconnect
}
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT)
select {
......
......@@ -218,6 +218,39 @@ func TestOutput(t *testing.T) {
}
}
// TestContinue verifies that the debugged executable starts immediately with --continue
func TestContinue(t *testing.T) {
const listenAddr = "localhost:40573"
dlvbin, tmpdir := getDlvBin(t)
defer os.RemoveAll(tmpdir)
buildtestdir := filepath.Join(protest.FindFixturesDir(), "buildtest")
cmd := exec.Command(dlvbin, "debug", "--headless", "--continue", "--accept-multiclient", "--listen", listenAddr)
cmd.Dir = buildtestdir
stdout, err := cmd.StdoutPipe()
assertNoError(err, t, "stderr pipe")
if err := cmd.Start(); err != nil {
t.Fatalf("could not start headless instance: %v", err)
}
scan := bufio.NewScanner(stdout)
// wait for the debugger to start
for scan.Scan() {
t.Log(scan.Text())
if scan.Text() == "hello world!" {
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))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册