mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	terminal: prompt to kill remote if process exited (#1621)
This commit is contained in:
		 Brian de Alwis
					Brian de Alwis
				
			
				
					committed by
					
						 Derek Parker
						Derek Parker
					
				
			
			
				
	
			
			
			 Derek Parker
						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