gdbserial: propagate unhandled signals back to a specific thread (#1749)

Instead of just sending unhandled signals back to the process send them
to the specific thread that received them.
This is important because:

1. debugserver does not appear to support the vCont;CXX packet without
specifying a target thread
2. the non-cooperative preemption change in an upcoming version of Go
(1.15?) will require sending signals to a specific thread.

Fixes #1744
This commit is contained in:
Alessandro Arzilli
2019-11-08 22:02:12 +01:00
committed by Derek Parker
parent e8d4ed7ece
commit 79143468ea
3 changed files with 9 additions and 10 deletions

View File

@ -355,6 +355,9 @@ func LLDBLaunch(cmd []string, wd string, foreground bool, debugInfoDirs []string
if foreground { if foreground {
args = append(args, "--stdio-path", "/dev/tty") args = append(args, "--stdio-path", "/dev/tty")
} }
if logflags.LLDBServerOutput() {
args = append(args, "-g", "-l", "stdout")
}
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...)
@ -657,7 +660,7 @@ func (p *Process) ContinueOnce() (proc.Thread, error) {
continueLoop: continueLoop:
for { for {
tu.Reset() tu.Reset()
threadID, sig, err = p.conn.resume(sig, &tu) threadID, sig, err = p.conn.resume(sig, threadID, &tu)
if err != nil { if err != nil {
if _, exited := err.(proc.ErrProcessExited); exited { if _, exited := err.(proc.ErrProcessExited); exited {
p.exited = true p.exited = true
@ -896,7 +899,7 @@ func (p *Process) Restart(pos string) error {
// for some reason we have to send a vCont;c after a vRun to make rr behave // for some reason we have to send a vCont;c after a vRun to make rr behave
// properly, because that's what gdb does. // properly, because that's what gdb does.
_, _, err = p.conn.resume(0, nil) _, _, err = p.conn.resume(0, "", nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -539,14 +539,15 @@ func (conn *gdbConn) writeRegister(threadID string, regnum int, data []byte) err
} }
// resume executes a 'vCont' command on all threads with action 'c' if sig // resume executes a 'vCont' command on all threads with action 'c' if sig
// is 0 or 'C' if it isn't. // is 0 or 'C' if it isn't. If sig isn't 0 a threadID should be specified as
func (conn *gdbConn) resume(sig uint8, tu *threadUpdater) (string, uint8, error) { // the target of the signal.
func (conn *gdbConn) resume(sig uint8, threadID string, tu *threadUpdater) (string, uint8, error) {
if conn.direction == proc.Forward { if conn.direction == proc.Forward {
conn.outbuf.Reset() conn.outbuf.Reset()
if sig == 0 { if sig == 0 {
fmt.Fprint(&conn.outbuf, "$vCont;c") fmt.Fprint(&conn.outbuf, "$vCont;c")
} else { } else {
fmt.Fprintf(&conn.outbuf, "$vCont;C%02x", sig) fmt.Fprintf(&conn.outbuf, "$vCont;C%02x:%s;c", sig, threadID)
} }
} else { } else {
if err := conn.selectThread('c', "p-1.-1", "resume"); err != nil { if err := conn.selectThread('c', "p-1.-1", "resume"); err != nil {

View File

@ -4,7 +4,6 @@ package proc_test
import ( import (
"fmt" "fmt"
"runtime"
"syscall" "syscall"
"testing" "testing"
"time" "time"
@ -23,10 +22,6 @@ func (npe errIssue419) Error() string {
} }
func TestIssue419(t *testing.T) { func TestIssue419(t *testing.T) {
if testBackend == "lldb" && runtime.GOOS == "darwin" {
// debugserver bug?
return
}
if testBackend == "rr" { if testBackend == "rr" {
return return
} }