Kill process outright if manually forked
This commit is contained in:
parent
e6448556fa
commit
40284111d4
14
proc/proc.go
14
proc/proc.go
@ -90,12 +90,14 @@ func Attach(pid int) (*Process, error) {
|
||||
|
||||
// Detach from the process being debugged, optionally killing it.
|
||||
func (dbp *Process) Detach(kill bool) (err error) {
|
||||
// Clean up any breakpoints we've set.
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if bp != nil {
|
||||
_, err := dbp.ClearBreakpoint(bp.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
if !kill {
|
||||
// Clean up any breakpoints we've set.
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if bp != nil {
|
||||
_, err := dbp.ClearBreakpoint(bp.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import "C"
|
||||
import (
|
||||
"debug/gosym"
|
||||
"debug/macho"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -81,6 +82,26 @@ func Launch(cmd []string) (*Process, error) {
|
||||
return dbp, err
|
||||
}
|
||||
|
||||
func (dbp *Process) Kill() (err error) {
|
||||
err = sys.Kill(dbp.Pid, sys.SIGKILL)
|
||||
if err != nil {
|
||||
return errors.New("could not deliver signal: " + err.Error())
|
||||
}
|
||||
for port := range dbp.Threads {
|
||||
if C.thread_resume(C.thread_act_t(port)) != C.KERN_SUCCESS {
|
||||
return errors.New("could not resume task")
|
||||
}
|
||||
}
|
||||
for {
|
||||
port := C.mach_port_wait(dbp.os.portSet)
|
||||
if port == dbp.os.notificationPort {
|
||||
break
|
||||
}
|
||||
}
|
||||
dbp.exited = true
|
||||
return
|
||||
}
|
||||
|
||||
func (dbp *Process) requestManualStop() (err error) {
|
||||
var (
|
||||
task = C.mach_port_t(dbp.os.task)
|
||||
|
@ -3,6 +3,7 @@ package proc
|
||||
import (
|
||||
"debug/elf"
|
||||
"debug/gosym"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -56,6 +57,22 @@ func Launch(cmd []string) (*Process, error) {
|
||||
return initializeDebugProcess(dbp, proc.Path, false)
|
||||
}
|
||||
|
||||
func (dbp *Process) Kill() (err error) {
|
||||
if !stopped(dbp.Pid) {
|
||||
return errors.New("process must be stopped in order to kill it")
|
||||
}
|
||||
err = sys.Kill(dbp.Pid, sys.SIGKILL)
|
||||
if err != nil {
|
||||
return errors.New("could not deliver signal " + err.Error())
|
||||
}
|
||||
_, _, err = wait(-1, dbp.Pid, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dbp.exited = true
|
||||
return
|
||||
}
|
||||
|
||||
func (dbp *Process) requestManualStop() (err error) {
|
||||
return sys.Kill(dbp.Pid, sys.SIGTRAP)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package proc
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -29,7 +30,7 @@ func withTestProcess(name string, t *testing.T, fn func(p *Process, fixture prot
|
||||
|
||||
defer func() {
|
||||
p.Halt()
|
||||
p.Detach(true)
|
||||
p.Kill()
|
||||
}()
|
||||
|
||||
fn(p, fixture)
|
||||
@ -531,3 +532,20 @@ func TestStacktraceGoroutine(t *testing.T) {
|
||||
p.Continue()
|
||||
})
|
||||
}
|
||||
|
||||
func TestKill(t *testing.T) {
|
||||
withTestProcess("testprog", t, func(p *Process, fixture protest.Fixture) {
|
||||
if err := p.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if p.Exited() != true {
|
||||
t.Fatal("expected process to have exited")
|
||||
}
|
||||
if runtime.GOOS == "linux" {
|
||||
_, err := os.Open(fmt.Sprintf("/proc/%d/", p.Pid))
|
||||
if err == nil {
|
||||
t.Fatal("process has not exited", p.Pid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -67,7 +67,11 @@ func (d *Debugger) ProcessPid() int {
|
||||
}
|
||||
|
||||
func (d *Debugger) Detach(kill bool) error {
|
||||
return d.process.Detach(kill)
|
||||
if d.config.AttachPid != 0 {
|
||||
return d.process.Detach(kill)
|
||||
} else {
|
||||
return d.process.Kill()
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Debugger) Restart() error {
|
||||
|
Loading…
Reference in New Issue
Block a user