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) {
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// 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)
{
// Declare all variables at top in case any
......@@ -132,6 +132,14 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
// 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
if dir != nil {
r1, r2, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0);
......@@ -217,8 +225,7 @@ childerror:
panic("unreached");
}
// Combination of fork and exec, careful to be thread safe.
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int)
(pid int, err int)
{
var p [2]int;
......@@ -257,7 +264,7 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
}
// 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 {
error:
if p[0] >= 0 {
......@@ -294,6 +301,20 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
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.
func Exec(argv0 string, argv []string, envv []string) (err int) {
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