mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 17:56:45 +08:00
terminal: prompt to kill remote if process exited (#1621)
This commit is contained in:
committed by
Derek Parker
parent
7d25f6eb97
commit
f67239f302
@ -3,6 +3,7 @@ package terminal
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/rpc"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -353,6 +354,18 @@ func (t *Term) handleExit() (int, error) {
|
|||||||
|
|
||||||
s, err := t.client.GetState()
|
s, err := t.client.GetState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isErrProcessExited(err) && t.client.IsMulticlient() {
|
||||||
|
answer, err := yesno(t.line, "Remote process has exited. Would you like to kill the headless instance? [Y/n] ")
|
||||||
|
if err != nil {
|
||||||
|
return 2, io.EOF
|
||||||
|
}
|
||||||
|
if answer {
|
||||||
|
if err := t.client.Detach(true); err != nil {
|
||||||
|
return 1, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
return 1, err
|
return 1, err
|
||||||
}
|
}
|
||||||
if !s.Exited {
|
if !s.Exited {
|
||||||
@ -404,3 +417,9 @@ func (t *Term) loadConfig() api.LoadConfig {
|
|||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isErrProcessExited returns true if `err` is an RPC error equivalent of proc.ErrProcessExited
|
||||||
|
func isErrProcessExited(err error) bool {
|
||||||
|
rpcError, ok := err.(rpc.ServerError)
|
||||||
|
return ok && strings.Contains(rpcError.Error(), "has exited with status")
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package terminal
|
package terminal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/rpc"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -85,3 +87,21 @@ func TestSubstitutePath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsErrProcessExited(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
err error
|
||||||
|
result bool
|
||||||
|
}{
|
||||||
|
{"empty error", errors.New(""), false},
|
||||||
|
{"non-ServerError", errors.New("Process 33122 has exited with status 0"), false},
|
||||||
|
{"ServerError with zero status", rpc.ServerError("Process 33122 has exited with status 0"), true},
|
||||||
|
{"ServerError with non-zero status", rpc.ServerError("Process 2 has exited with status 25"), true},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if isErrProcessExited(test.err) != test.result {
|
||||||
|
t.Error(test.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user