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 {
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, cmd...)
@ -657,7 +660,7 @@ func (p *Process) ContinueOnce() (proc.Thread, error) {
continueLoop:
for {
tu.Reset()
threadID, sig, err = p.conn.resume(sig, &tu)
threadID, sig, err = p.conn.resume(sig, threadID, &tu)
if err != nil {
if _, exited := err.(proc.ErrProcessExited); exited {
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
// properly, because that's what gdb does.
_, _, err = p.conn.resume(0, nil)
_, _, err = p.conn.resume(0, "", nil)
if err != nil {
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
// is 0 or 'C' if it isn't.
func (conn *gdbConn) resume(sig uint8, tu *threadUpdater) (string, uint8, error) {
// is 0 or 'C' if it isn't. If sig isn't 0 a threadID should be specified as
// the target of the signal.
func (conn *gdbConn) resume(sig uint8, threadID string, tu *threadUpdater) (string, uint8, error) {
if conn.direction == proc.Forward {
conn.outbuf.Reset()
if sig == 0 {
fmt.Fprint(&conn.outbuf, "$vCont;c")
} else {
fmt.Fprintf(&conn.outbuf, "$vCont;C%02x", sig)
fmt.Fprintf(&conn.outbuf, "$vCont;C%02x:%s;c", sig, threadID)
}
} else {
if err := conn.selectThread('c', "p-1.-1", "resume"); err != nil {

View File

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