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.
|
// Detach from the process being debugged, optionally killing it.
|
||||||
func (dbp *Process) Detach(kill bool) (err error) {
|
func (dbp *Process) Detach(kill bool) (err error) {
|
||||||
// Clean up any breakpoints we've set.
|
if !kill {
|
||||||
for _, bp := range dbp.Breakpoints {
|
// Clean up any breakpoints we've set.
|
||||||
if bp != nil {
|
for _, bp := range dbp.Breakpoints {
|
||||||
_, err := dbp.ClearBreakpoint(bp.Addr)
|
if bp != nil {
|
||||||
if err != nil {
|
_, err := dbp.ClearBreakpoint(bp.Addr)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
"debug/macho"
|
"debug/macho"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -81,6 +82,26 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
return dbp, err
|
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) {
|
func (dbp *Process) requestManualStop() (err error) {
|
||||||
var (
|
var (
|
||||||
task = C.mach_port_t(dbp.os.task)
|
task = C.mach_port_t(dbp.os.task)
|
||||||
|
@ -3,6 +3,7 @@ package proc
|
|||||||
import (
|
import (
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -56,6 +57,22 @@ func Launch(cmd []string) (*Process, error) {
|
|||||||
return initializeDebugProcess(dbp, proc.Path, false)
|
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) {
|
func (dbp *Process) requestManualStop() (err error) {
|
||||||
return sys.Kill(dbp.Pid, sys.SIGTRAP)
|
return sys.Kill(dbp.Pid, sys.SIGTRAP)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package proc
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -29,7 +30,7 @@ func withTestProcess(name string, t *testing.T, fn func(p *Process, fixture prot
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
p.Halt()
|
p.Halt()
|
||||||
p.Detach(true)
|
p.Kill()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fn(p, fixture)
|
fn(p, fixture)
|
||||||
@ -531,3 +532,20 @@ func TestStacktraceGoroutine(t *testing.T) {
|
|||||||
p.Continue()
|
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 {
|
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 {
|
func (d *Debugger) Restart() error {
|
||||||
|
Loading…
Reference in New Issue
Block a user