From 7c7265f4e68a333bb084217e7b7ae065024e428b Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Fri, 17 May 2024 01:07:20 +0200 Subject: [PATCH] gdbserial: fixes for rr 5.7.0 (#3718) The following fixes have been applied to make delve work with rr 5.7.0 - added a new launch prefix to exclude from stderr output - allow the thread selection packet to be sent for 'c' commands even when the stub supports thread suffixes, because the specification is unclear over what should be done with bc and bs packets with thread suffixes. - changed the way qRRCmd are escaped and added a thread selector to them to match changes to rr codebase --- pkg/proc/gdbserial/gdbserver_conn.go | 15 ++++++++++++--- pkg/proc/gdbserial/rr.go | 9 +++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pkg/proc/gdbserial/gdbserver_conn.go b/pkg/proc/gdbserial/gdbserver_conn.go index fc9f6aa499..6a90fc0ddb 100644 --- a/pkg/proc/gdbserial/gdbserver_conn.go +++ b/pkg/proc/gdbserial/gdbserver_conn.go @@ -985,7 +985,10 @@ func (conn *gdbConn) queryThreads(first bool) (threads []string, err error) { } func (conn *gdbConn) selectThread(kind byte, threadID string, context string) error { - if conn.threadSuffixSupported { + if conn.threadSuffixSupported && kind != 'c' { + // kind == 'c' is still allowed because 'rr' is weird about it's support + // for thread suffixes and the specification for it doesn't really say how + // it should be used with packets 'bc' and 'bs'. panic("selectThread when thread suffix is supported") } conn.outbuf.Reset() @@ -1189,9 +1192,15 @@ func (conn *gdbConn) qRRCmd(args ...string) (string, error) { } conn.outbuf.Reset() fmt.Fprint(&conn.outbuf, "$qRRCmd") - for _, arg := range args { + for i, arg := range args { fmt.Fprint(&conn.outbuf, ":") - writeAsciiBytes(&conn.outbuf, []byte(arg)) + if i == 0 && conn.threadSuffixSupported { + // newer versions of RR require the command to be followed by a thread id + // and the command name to be unescaped. + fmt.Fprintf(&conn.outbuf, "%s:-1", arg) + } else { + writeAsciiBytes(&conn.outbuf, []byte(arg)) + } } resp, err := conn.exec(conn.outbuf.Bytes(), "qRRCmd") if err != nil { diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index ecaa882021..3fdff59b93 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -217,9 +217,10 @@ type rrInit struct { const ( rrGdbCommandLegacyPrefix = " gdb " - rrGdbCommandPrefix = " 'gdb' " - rrGdbLaunchPrefix = "Launch gdb with" - targetCmd = "target extended-remote " + rrGdbCommandPrefix = " 'gdb' " + rrGdbLaunchLegacyPrefix = "Launch gdb with" + rrGdbLaunchPrefix = "Launch debugger with" + targetCmd = "target extended-remote " ) func rrStderrParser(stderr io.ReadCloser, initch chan<- rrInit, quiet bool) { @@ -245,7 +246,7 @@ func rrStderrParser(stderr io.ReadCloser, initch chan<- rrInit, quiet bool) { break } - if strings.HasPrefix(line, rrGdbLaunchPrefix) { + if strings.HasPrefix(line, rrGdbLaunchPrefix) || strings.HasPrefix(line, rrGdbLaunchLegacyPrefix) { continue }