Commit 14bb806c authored by Austin Clements's avatar Austin Clements

Support ptracing of fork'd children.

R=rsc
APPROVED=rsc
DELTA=26  (22 added, 1 deleted, 3 changed)
OCL=31613
CL=31629
parent 40f406af
...@@ -99,7 +99,7 @@ func SetNonblock(fd int, nonblocking bool) (errno int) { ...@@ -99,7 +99,7 @@ func SetNonblock(fd int, nonblocking bool) (errno int) {
// no rescheduling, no malloc calls, and no new stack segments. // no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly // The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack. // functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int, pipe int) func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, dir *byte, fd []int, pipe int)
(pid int, err int) (pid int, err int)
{ {
// Declare all variables at top in case any // Declare all variables at top in case any
...@@ -132,6 +132,14 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [ ...@@ -132,6 +132,14 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
// Fork succeeded, now in child. // Fork succeeded, now in child.
// Enable tracing if requested.
if traceme {
r1, r2, err1 = RawSyscall(SYS_PTRACE, uintptr(_PTRACE_TRACEME), 0, 0);
if err1 != 0 {
goto childerror;
}
}
// Chdir // Chdir
if dir != nil { if dir != nil {
r1, r2, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0); r1, r2, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0);
...@@ -217,8 +225,7 @@ childerror: ...@@ -217,8 +225,7 @@ childerror:
panic("unreached"); panic("unreached");
} }
// Combination of fork and exec, careful to be thread safe. func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int)
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
(pid int, err int) (pid int, err int)
{ {
var p [2]int; var p [2]int;
...@@ -257,7 +264,7 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) ...@@ -257,7 +264,7 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
} }
// Kick off child. // Kick off child.
pid, err = forkAndExecInChild(argv0p, argvp, envvp, dirp, fd, p[1]); pid, err = forkAndExecInChild(argv0p, argvp, envvp, traceme, dirp, fd, p[1]);
if err != 0 { if err != 0 {
error: error:
if p[0] >= 0 { if p[0] >= 0 {
...@@ -294,6 +301,20 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) ...@@ -294,6 +301,20 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
return pid, 0 return pid, 0
} }
// Combination of fork and exec, careful to be thread safe.
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
(pid int, err int)
{
return forkExec(argv0, argv, envv, false, dir, fd);
}
// PtraceForkExec is like ForkExec, but starts the child in a traced state.
func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
(pid int, err int)
{
return forkExec(argv0, argv, envv, true, dir, fd);
}
// Ordinary exec. // Ordinary exec.
func Exec(argv0 string, argv []string, envv []string) (err int) { func Exec(argv0 string, argv []string, envv []string) (err int) {
r1, r2, err1 := RawSyscall(SYS_EXECVE, r1, r2, err1 := RawSyscall(SYS_EXECVE,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment