proc/gdbserial: use reverse connect feature of debugserver (#837)

Fixes #836
This commit is contained in:
Alessandro Arzilli 2017-05-11 21:34:39 +02:00 committed by Derek Parker
parent 862145f874
commit 82d142d1cd
2 changed files with 42 additions and 20 deletions

@ -86,6 +86,7 @@ const (
showLldbServerOutput = false
logGdbWireMaxLen = 120
maxConnectAttempts = 10 // number of connection attempts to stub
maxTransmitAttempts = 3 // number of retransmission attempts on failed checksum
initialInputBufferSize = 2048 // size of the input buffer for gdbConn
)
@ -152,14 +153,24 @@ type gdbRegister struct {
regnum int
}
// Connect creates a GdbserverProcess connected to address addr.
// Connect connects to a stub and performs a handshake.
//
// If listener is not nil Connect will accept a connection from the stub
// (which should be instructed to operate in client mode), otherwise it will
// connect to addr.
//
// Path and pid are, respectively, the path to the executable of the target
// program and the PID of the target process, both are optional, however
// some stubs do not provide ways to determine path and pid automatically
// and Connect will be unable to function without knowing them.
func Connect(addr string, path string, pid int, attempts int) (*Process, error) {
func Connect(listener net.Listener, addr string, path string, pid int, attempts int) (*Process, error) {
var conn net.Conn
var err error
if listener != nil {
conn, err = listener.Accept()
listener.Close()
} else {
for i := 0; i < attempts; i++ {
conn, err = net.Dial("tcp", addr)
if err == nil {
@ -167,6 +178,7 @@ func Connect(addr string, path string, pid int, attempts int) (*Process, error)
}
time.Sleep(time.Second)
}
}
if err != nil {
return nil, err
}
@ -282,11 +294,7 @@ func Connect(addr string, path string, pid int, attempts int) (*Process, error)
// before reassigning one port they just assigned, unless there's heavy
// churn in the ephemeral range this should work.
func unusedPort() string {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return ":8081"
}
listener, err := net.ListenTCP("tcp", addr)
listener, err := net.Listen("tcp", "localhost:0")
if err != nil {
return ":8081"
}
@ -313,19 +321,26 @@ func LLDBLaunch(cmd []string, wd string) (*Process, error) {
}
}
port := unusedPort()
isDebugserver := false
var listener net.Listener
var port string
var proc *exec.Cmd
if _, err := os.Stat(debugserverExecutable); err == nil {
args := make([]string, 0, len(cmd)+2)
args = append(args, "-F", "127.0.0.1"+port)
listener, err = net.Listen("tcp", "localhost:0")
if err != nil {
return nil, err
}
listener.(*net.TCPListener).SetDeadline(time.Now().Add(maxConnectAttempts * time.Second))
args := make([]string, 0, len(cmd)+3)
args = append(args, "-F", "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port))
args = append(args, cmd...)
isDebugserver = true
proc = exec.Command(debugserverExecutable, args...)
} else {
port = unusedPort()
args := make([]string, 0, len(cmd)+3)
args = append(args, "gdbserver")
args = append(args, port, "--")
@ -349,7 +364,7 @@ func LLDBLaunch(cmd []string, wd string) (*Process, error) {
return nil, err
}
p, err := Connect(port, cmd[0], 0, 10)
p, err := Connect(listener, port, cmd[0], 0, maxConnectAttempts)
if err != nil {
return nil, err
}
@ -370,13 +385,20 @@ func LLDBAttach(pid int, path string) (*Process, error) {
return nil, ErrUnsupportedOS
}
port := unusedPort()
isDebugserver := false
var proc *exec.Cmd
var listener net.Listener
var port string
if _, err := os.Stat(debugserverExecutable); err == nil {
isDebugserver = true
proc = exec.Command(debugserverExecutable, "127.0.0.1"+port, "--attach="+strconv.Itoa(pid))
listener, err = net.Listen("tcp", "localhost:0")
if err != nil {
return nil, err
}
listener.(*net.TCPListener).SetDeadline(time.Now().Add(maxConnectAttempts * time.Second))
proc = exec.Command(debugserverExecutable, "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--attach="+strconv.Itoa(pid))
} else {
port = unusedPort()
proc = exec.Command("lldb-server", "gdbserver", "--attach", strconv.Itoa(pid), port)
}
@ -390,7 +412,7 @@ func LLDBAttach(pid int, path string) (*Process, error) {
return nil, err
}
p, err := Connect(port, path, pid, 10)
p, err := Connect(listener, port, path, pid, maxConnectAttempts)
if err != nil {
return nil, err
}

@ -70,7 +70,7 @@ func Replay(tracedir string, quiet bool) (*Process, error) {
rrcmd.Process.Kill()
return nil, err
}
p, err := Connect(init.port, init.exe, 0, 10)
p, err := Connect(nil, init.port, init.exe, 0, maxConnectAttempts)
if err != nil {
rrcmd.Process.Kill()
return nil, err