mirror of
https://github.com/go-delve/delve.git
synced 2025-10-28 20:53:42 +08:00
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:
committed by
Derek Parker
parent
e8d4ed7ece
commit
79143468ea
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user