proc/gdbserial: use --unmask-signal debugserver option (#2255)

Fixes #852

Co-authored-by: a <a@kra>
This commit is contained in:
Alessandro Arzilli
2020-12-10 18:04:35 +01:00
committed by GitHub
parent d3e9158e9e
commit fbfad81968

View File

@ -74,6 +74,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"golang.org/x/arch/x86/x86asm" "golang.org/x/arch/x86/x86asm"
@ -90,6 +91,8 @@ const (
maxTransmitAttempts = 3 // number of retransmission attempts on failed checksum maxTransmitAttempts = 3 // number of retransmission attempts on failed checksum
initialInputBufferSize = 2048 // size of the input buffer for gdbConn initialInputBufferSize = 2048 // size of the input buffer for gdbConn
debugServerEnvVar = "DELVE_DEBUGSERVER_PATH" // use this environment variable to override the path to debugserver used by Launch/Attach
) )
const heartbeatInterval = 10 * time.Second const heartbeatInterval = 10 * time.Second
@ -126,6 +129,9 @@ var debugserverExecutablePaths = []string{
// while there are still internal breakpoints set. // while there are still internal breakpoints set.
var ErrDirChange = errors.New("direction change with internal breakpoints") var ErrDirChange = errors.New("direction change with internal breakpoints")
var checkCanUnmaskSignalsOnce sync.Once
var canUnmaskSignalsCached bool
// gdbProcess implements proc.Process using a connection to a debugger stub // gdbProcess implements proc.Process using a connection to a debugger stub
// that understands Gdb Remote Serial Protocol. // that understands Gdb Remote Serial Protocol.
type gdbProcess struct { type gdbProcess struct {
@ -330,6 +336,9 @@ func unusedPort() string {
// getDebugServerAbsolutePath returns a string of the absolute path to the debugserver binary IFF it is // getDebugServerAbsolutePath returns a string of the absolute path to the debugserver binary IFF it is
// found in the system path ($PATH), the Xcode bundle or the standalone CLT location. // found in the system path ($PATH), the Xcode bundle or the standalone CLT location.
func getDebugServerAbsolutePath() string { func getDebugServerAbsolutePath() string {
if path := os.Getenv(debugServerEnvVar); path != "" {
return path
}
for _, debugServerPath := range debugserverExecutablePaths { for _, debugServerPath := range debugserverExecutablePaths {
if debugServerPath == "" { if debugServerPath == "" {
continue continue
@ -341,6 +350,14 @@ func getDebugServerAbsolutePath() string {
return "" return ""
} }
func canUnmaskSignals(debugServerExecutable string) bool {
checkCanUnmaskSignalsOnce.Do(func() {
buf, _ := exec.Command(debugServerExecutable, "--unmask-singals").CombinedOutput()
canUnmaskSignalsCached = !strings.Contains(string(buf), "unrecognized option")
})
return canUnmaskSignalsCached
}
// commandLogger is a wrapper around the exec.Command() function to log the arguments prior to // commandLogger is a wrapper around the exec.Command() function to log the arguments prior to
// starting the process // starting the process
func commandLogger(binary string, arguments ...string) *exec.Cmd { func commandLogger(binary string, arguments ...string) *exec.Cmd {
@ -421,6 +438,9 @@ func LLDBLaunch(cmd []string, wd string, flags proc.LaunchFlags, debugInfoDirs [
if flags&proc.LaunchDisableASLR != 0 { if flags&proc.LaunchDisableASLR != 0 {
args = append(args, "-D") args = append(args, "-D")
} }
if canUnmaskSignals(debugserverExecutable) {
args = append(args, "--unmask-signals")
}
args = append(args, "-F", "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--") args = append(args, "-F", "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--")
args = append(args, cmd...) args = append(args, cmd...)
@ -500,7 +520,11 @@ func LLDBAttach(pid int, path string, debugInfoDirs []string) (*proc.Target, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
process = commandLogger(debugserverExecutable, "-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--attach="+strconv.Itoa(pid)) args := []string{"-R", fmt.Sprintf("127.0.0.1:%d", listener.Addr().(*net.TCPAddr).Port), "--attach=" + strconv.Itoa(pid)}
if canUnmaskSignals(debugserverExecutable) {
args = append(args, "--unmask-signals")
}
process = commandLogger(debugserverExecutable, args...)
} else { } else {
if _, err = exec.LookPath("lldb-server"); err != nil { if _, err = exec.LookPath("lldb-server"); err != nil {
return nil, &ErrBackendUnavailable{} return nil, &ErrBackendUnavailable{}