cmd/dlv,terminal: fix accept-multiclient behavior
1. Check IsMulticlient and send stop request before doing anything else. 2. Allow init file to call 'exit' Fixes #1430
This commit is contained in:
parent
cb386d0966
commit
d7d4c144c8
1
_fixtures/exit.init
Normal file
1
_fixtures/exit.init
Normal file
@ -0,0 +1 @@
|
||||
exit
|
@ -500,6 +500,20 @@ func connect(addr string, clientConn net.Conn, conf *config.Config, kind execute
|
||||
} else {
|
||||
client = rpc2.NewClient(addr)
|
||||
}
|
||||
if client.IsMulticlient() {
|
||||
state, _ := client.GetStateNonBlocking()
|
||||
// The error return of GetState will usually be the ErrProcessExited,
|
||||
// which we don't care about. If there are other errors they will show up
|
||||
// later, here we are only concerned about stopping a running target so
|
||||
// that we can initialize our connection.
|
||||
if state != nil && state.Running {
|
||||
_, err := client.Halt()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not halt: %v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if client.Recorded() && (kind == executingGeneratedFile || kind == executingGeneratedTest) {
|
||||
// When using the rr backend remove the trace directory if we built the
|
||||
// executable
|
||||
|
@ -256,3 +256,20 @@ func TestGeneratedDoc(t *testing.T) {
|
||||
checkAutogenDoc(t, docFilename, "scripts/gen-usage-docs.go", slurpFile(t, tempDir+"/"+doc.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestExitInInit(t *testing.T) {
|
||||
dlvbin, tmpdir := getDlvBin(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
buildtestdir := filepath.Join(protest.FindFixturesDir(), "buildtest")
|
||||
exitInit := filepath.Join(protest.FindFixturesDir(), "exit.init")
|
||||
cmd := exec.Command(dlvbin, "--init", exitInit, "debug")
|
||||
cmd.Dir = buildtestdir
|
||||
out, err := cmd.CombinedOutput()
|
||||
t.Logf("%q %v\n", string(out), err)
|
||||
// dlv will exit anyway because stdin is not a tty but it will print the
|
||||
// prompt once if the init file didn't call exit successfully.
|
||||
if strings.Contains(string(out), "(dlv)") {
|
||||
t.Fatal("init did not cause dlv to exit")
|
||||
}
|
||||
}
|
||||
|
@ -1933,6 +1933,9 @@ func (c *Commands) executeFile(t *Term, name string) error {
|
||||
}
|
||||
|
||||
if err := c.Call(line, t); err != nil {
|
||||
if _, isExitRequest := err.(ExitRequestError); isExitRequest {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s:%d: %v\n", name, lineno, err)
|
||||
}
|
||||
}
|
||||
|
@ -64,20 +64,6 @@ type Term struct {
|
||||
|
||||
// New returns a new Term.
|
||||
func New(client service.Client, conf *config.Config) *Term {
|
||||
if client != nil && client.IsMulticlient() {
|
||||
state, _ := client.GetStateNonBlocking()
|
||||
// The error return of GetState will usually be the ErrProcessExited,
|
||||
// which we don't care about. If there are other errors they will show up
|
||||
// later, here we are only concerned about stopping a running target so
|
||||
// that we can initialize our connection.
|
||||
if state != nil && state.Running {
|
||||
_, err := client.Halt()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not halt: %v", err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
cmds := DebugCommands(client)
|
||||
if conf != nil && conf.Aliases != nil {
|
||||
cmds.Merge(conf.Aliases)
|
||||
@ -204,6 +190,9 @@ func (t *Term) Run() (int, error) {
|
||||
if t.InitFile != "" {
|
||||
err := t.cmds.executeFile(t, t.InitFile)
|
||||
if err != nil {
|
||||
if _, ok := err.(ExitRequestError); ok {
|
||||
return t.handleExit()
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Error executing init file: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user