]> Cypherpunks repositories - gostls13.git/commitdiff
Support ptracing of fork'd children.
authorAustin Clements <aclements@csail.mit.edu>
Tue, 14 Jul 2009 22:09:39 +0000 (15:09 -0700)
committerAustin Clements <aclements@csail.mit.edu>
Tue, 14 Jul 2009 22:09:39 +0000 (15:09 -0700)
R=rsc
APPROVED=rsc
DELTA=26  (22 added, 1 deleted, 3 changed)
OCL=31613
CL=31629

src/pkg/syscall/exec.go

index 58fb058635f6e5e97e9914ae9480a3c9ba7cb58a..3dd0727f81ad1673d26707278ff79ed53e85ea54 100644 (file)
@@ -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,