proc/native: wherever we check for exited we should also check detached (#3547)

Only Linux and Windows are affected but it's better to do this for all
platforms for consistency.
This commit is contained in:
Alessandro Arzilli
2023-10-31 18:18:46 +01:00
committed by GitHub
parent 96a6db9d36
commit 0631684f99
9 changed files with 33 additions and 35 deletions

View File

@ -106,7 +106,7 @@ func detachWithoutGroup(dbp *nativeProcess, kill bool) error {
// Detach from the process being debugged, optionally killing it. // Detach from the process being debugged, optionally killing it.
func (procgrp *processGroup) Detach(pid int, kill bool) (err error) { func (procgrp *processGroup) Detach(pid int, kill bool) (err error) {
dbp := procgrp.procForPid(pid) dbp := procgrp.procForPid(pid)
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
return nil return nil
} }
if kill && dbp.childProcess { if kill && dbp.childProcess {
@ -170,8 +170,8 @@ func (dbp *nativeProcess) Breakpoints() *proc.BreakpointMap {
// RequestManualStop sets the `manualStopRequested` flag and // RequestManualStop sets the `manualStopRequested` flag and
// sends SIGSTOP to all threads. // sends SIGSTOP to all threads.
func (dbp *nativeProcess) RequestManualStop(cctx *proc.ContinueOnceContext) error { func (dbp *nativeProcess) RequestManualStop(cctx *proc.ContinueOnceContext) error {
if dbp.exited { if ok, err := dbp.Valid(); !ok {
return proc.ErrProcessExited{Pid: dbp.pid} return err
} }
return dbp.requestManualStop() return dbp.requestManualStop()
} }
@ -300,7 +300,7 @@ func (procgrp *processGroup) ContinueOnce(cctx *proc.ContinueOnceContext) (proc.
dbp.memthread = trapthread dbp.memthread = trapthread
// refresh memthread for every other process // refresh memthread for every other process
for _, p2 := range procgrp.procs { for _, p2 := range procgrp.procs {
if p2.exited || p2 == dbp { if p2.exited || p2.detached || p2 == dbp {
continue continue
} }
for _, th := range p2.threads { for _, th := range p2.threads {

View File

@ -183,7 +183,7 @@ func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, erro
// Kill kills the process. // Kill kills the process.
func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) { func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
return nil return nil
} }
err = sys.Kill(-dbp.pid, sys.SIGKILL) err = sys.Kill(-dbp.pid, sys.SIGKILL)
@ -449,8 +449,8 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
} }
func (dbp *nativeProcess) stop(trapthread *nativeThread) (*nativeThread, error) { func (dbp *nativeProcess) stop(trapthread *nativeThread) (*nativeThread, error) {
if dbp.exited { if ok, err := dbp.Valid(); !ok {
return nil, proc.ErrProcessExited{Pid: dbp.pid} return nil, err
} }
for _, th := range dbp.threads { for _, th := range dbp.threads {
if !th.Stopped() { if !th.Stopped() {

View File

@ -206,7 +206,7 @@ func initialize(dbp *nativeProcess) (string, error) {
// kill kills the target process. // kill kills the target process.
func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) { func (procgrp *processGroup) kill(dbp *nativeProcess) (err error) {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
return nil return nil
} }
dbp.execPtraceFunc(func() { dbp.execPtraceFunc(func() {
@ -508,8 +508,8 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
} }
func (dbp *nativeProcess) stop(trapthread *nativeThread) (*nativeThread, error) { func (dbp *nativeProcess) stop(trapthread *nativeThread) (*nativeThread, error) {
if dbp.exited { if ok, err := dbp.Valid(); !ok {
return nil, proc.ErrProcessExited{Pid: dbp.pid} return nil, err
} }
var err error var err error

View File

@ -261,7 +261,7 @@ func (dbp *nativeProcess) GetBufferedTracepoints() []ebpf.RawUProbeParams {
// kill kills the target process. // kill kills the target process.
func (procgrp *processGroup) kill(dbp *nativeProcess) error { func (procgrp *processGroup) kill(dbp *nativeProcess) error {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
return nil return nil
} }
if !dbp.threads[dbp.pid].Stopped() { if !dbp.threads[dbp.pid].Stopped() {
@ -680,7 +680,7 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
} }
for _, dbp := range procgrp.procs { for _, dbp := range procgrp.procs {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
continue continue
} }
for _, th := range dbp.threads { for _, th := range dbp.threads {
@ -703,7 +703,7 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
// stop all threads that are still running // stop all threads that are still running
for _, dbp := range procgrp.procs { for _, dbp := range procgrp.procs {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
continue continue
} }
for _, th := range dbp.threads { for _, th := range dbp.threads {
@ -724,7 +724,7 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
for { for {
allstopped := true allstopped := true
for _, dbp := range procgrp.procs { for _, dbp := range procgrp.procs {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
continue continue
} }
for _, th := range dbp.threads { for _, th := range dbp.threads {
@ -746,7 +746,7 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
switchTrapthread := false switchTrapthread := false
for _, dbp := range procgrp.procs { for _, dbp := range procgrp.procs {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
continue continue
} }
err := stop1(cctx, dbp, trapthread, &switchTrapthread) err := stop1(cctx, dbp, trapthread, &switchTrapthread)
@ -759,7 +759,7 @@ func (procgrp *processGroup) stop(cctx *proc.ContinueOnceContext, trapthread *na
trapthreadID := trapthread.ID trapthreadID := trapthread.ID
trapthread = nil trapthread = nil
for _, dbp := range procgrp.procs { for _, dbp := range procgrp.procs {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
continue continue
} }
for _, th := range dbp.threads { for _, th := range dbp.threads {

View File

@ -259,7 +259,7 @@ func waitForSearchProcess(pfx string, seen map[int]struct{}) (int, error) {
// kill kills the process. // kill kills the process.
func (procgrp *processGroup) kill(dbp *nativeProcess) error { func (procgrp *processGroup) kill(dbp *nativeProcess) error {
if dbp.exited { if ok, _ := dbp.Valid(); !ok {
return nil return nil
} }

View File

@ -93,8 +93,8 @@ func (t *nativeThread) Stopped() bool {
} }
func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) { func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return 0, nil return 0, nil
@ -111,8 +111,8 @@ func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) {
} }
func (t *nativeThread) ReadMemory(buf []byte, addr uint64) (int, error) { func (t *nativeThread) ReadMemory(buf []byte, addr uint64) (int, error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(buf) == 0 { if len(buf) == 0 {
return 0, nil return 0, nil

View File

@ -77,8 +77,8 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
} }
func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err error) { func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return 0, nil return 0, nil
@ -88,8 +88,8 @@ func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err e
} }
func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) { func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return 0, nil return 0, nil

View File

@ -88,8 +88,8 @@ func (procgrp *processGroup) singleStep(t *nativeThread) (err error) {
} }
func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err error) { func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return return
@ -106,8 +106,8 @@ func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err e
} }
func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) { func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return return

View File

@ -5,8 +5,6 @@ import (
"syscall" "syscall"
sys "golang.org/x/sys/windows" sys "golang.org/x/sys/windows"
"github.com/go-delve/delve/pkg/proc"
) )
const enableHardwareBreakpoints = false // see https://github.com/go-delve/delve/issues/2768 const enableHardwareBreakpoints = false // see https://github.com/go-delve/delve/issues/2768
@ -106,8 +104,8 @@ func (procgrp *processGroup) singleStep(t *nativeThread) error {
} }
func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) { func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(data) == 0 { if len(data) == 0 {
return 0, nil return 0, nil
@ -123,8 +121,8 @@ func (t *nativeThread) WriteMemory(addr uint64, data []byte) (int, error) {
var ErrShortRead = errors.New("short read") var ErrShortRead = errors.New("short read")
func (t *nativeThread) ReadMemory(buf []byte, addr uint64) (int, error) { func (t *nativeThread) ReadMemory(buf []byte, addr uint64) (int, error) {
if t.dbp.exited { if ok, err := t.dbp.Valid(); !ok {
return 0, proc.ErrProcessExited{Pid: t.dbp.pid} return 0, err
} }
if len(buf) == 0 { if len(buf) == 0 {
return 0, nil return 0, nil