Return error when invoking Delve with invalid path

Fixes #154
This commit is contained in:
Derek Parker 2015-06-26 23:05:15 -05:00
parent 24c024d1e6
commit 29ed169848
5 changed files with 54 additions and 12 deletions

@ -61,6 +61,13 @@ func main() {
os.Exit(0) os.Exit(0)
} }
defer func() {
if err := recover(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}()
status := run(addr, logEnabled, headless) status := run(addr, logEnabled, headless)
fmt.Println("[Hope I was of service hunting your bug!]") fmt.Println("[Hope I was of service hunting your bug!]")
os.Exit(status) os.Exit(status)
@ -121,6 +128,7 @@ func run(addr string, logEnabled, headless bool) int {
fmt.Printf("couldn't start listener: %s\n", err) fmt.Printf("couldn't start listener: %s\n", err)
return 1 return 1
} }
defer listener.Close()
// Create and start a debugger server // Create and start a debugger server
var server service.Server var server service.Server
@ -129,7 +137,10 @@ func run(addr string, logEnabled, headless bool) int {
ProcessArgs: processArgs, ProcessArgs: processArgs,
AttachPid: attachPid, AttachPid: attachPid,
}, logEnabled) }, logEnabled)
go server.Run() if err := server.Run(); err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
var status int var status int
if !headless { if !headless {

@ -9,6 +9,7 @@ import (
"debug/macho" "debug/macho"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"sync" "sync"
"unsafe" "unsafe"
@ -38,8 +39,18 @@ func Launch(cmd []string) (*Process, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if filepath.Base(cmd[0]) == cmd[0] {
if _, err := exec.LookPath(cmd[0]); err != nil {
return nil, err
}
}
argv0 := C.CString(argv0Go) argv0 := C.CString(argv0Go)
// Make sure the binary exists.
if _, err := os.Stat(argv0Go); err != nil {
return nil, err
}
argvSlice := make([]*C.char, 0, len(cmd)) argvSlice := make([]*C.char, 0, len(cmd))
for _, arg := range cmd { for _, arg := range cmd {
argvSlice = append(argvSlice, C.CString(arg)) argvSlice = append(argvSlice, C.CString(arg))

@ -46,14 +46,14 @@ func New(config *Config) (*Debugger, error) {
log.Printf("attaching to pid %d", d.config.AttachPid) log.Printf("attaching to pid %d", d.config.AttachPid)
p, err := proc.Attach(d.config.AttachPid) p, err := proc.Attach(d.config.AttachPid)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't attach to pid %d: %s", d.config.AttachPid, err) return nil, fmt.Errorf("could not attach to pid %d: %s", d.config.AttachPid, err)
} }
d.process = p d.process = p
} else { } else {
log.Printf("launching process with args: %v", d.config.ProcessArgs) log.Printf("launching process with args: %v", d.config.ProcessArgs)
p, err := proc.Launch(d.config.ProcessArgs) p, err := proc.Launch(d.config.ProcessArgs)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't launch process: %s", err) return nil, fmt.Errorf("could not launch process: %s", err)
} }
d.process = p d.process = p
} }

@ -45,11 +45,7 @@ func (s *RPCServer) Stop(kill bool) error {
// itself can be stopped with the `detach` API. Run blocks until the HTTP // itself can be stopped with the `detach` API. Run blocks until the HTTP
// server stops. // server stops.
func (s *RPCServer) Run() error { func (s *RPCServer) Run() error {
c, err := s.listener.Accept() var err error
if err != nil {
return err
}
// Create and start the debugger // Create and start the debugger
if s.debugger, err = debugger.New(&debugger.Config{ if s.debugger, err = debugger.New(&debugger.Config{
ProcessArgs: s.config.ProcessArgs, ProcessArgs: s.config.ProcessArgs,
@ -58,9 +54,16 @@ func (s *RPCServer) Run() error {
return err return err
} }
rpcs := grpc.NewServer() go func() {
rpcs.Register(s) c, err := s.listener.Accept()
rpcs.ServeCodec(jsonrpc.NewServerCodec(c)) if err != nil {
panic(err)
}
rpcs := grpc.NewServer()
rpcs.Register(s)
rpcs.ServeCodec(jsonrpc.NewServerCodec(c))
}()
return nil return nil
} }

@ -33,7 +33,9 @@ func withTestClient(name string, t *testing.T, fn func(c service.Client)) {
Listener: listener, Listener: listener,
ProcessArgs: []string{protest.BuildFixture(name).Path}, ProcessArgs: []string{protest.BuildFixture(name).Path},
}, false) }, false)
go server.Run() if err := server.Run(); err != nil {
t.Fatal(err)
}
client := rpc.NewClient(listener.Addr().String()) client := rpc.NewClient(listener.Addr().String())
defer func() { defer func() {
client.Detach(true) client.Detach(true)
@ -42,6 +44,21 @@ func withTestClient(name string, t *testing.T, fn func(c service.Client)) {
fn(client) fn(client)
} }
func TestRunWithInvalidPath(t *testing.T) {
listener, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("couldn't start listener: %s\n", err)
}
defer listener.Close()
server := rpc.NewServer(&service.Config{
Listener: listener,
ProcessArgs: []string{"invalid_path"},
}, false)
if err := server.Run(); err == nil {
t.Fatal("Expected Run to return error for invalid program path")
}
}
func TestClientServer_exit(t *testing.T) { func TestClientServer_exit(t *testing.T) {
withTestClient("continuetestprog", t, func(c service.Client) { withTestClient("continuetestprog", t, func(c service.Client) {
state, err := c.GetState() state, err := c.GetState()