From 14bb806cb4791f0c7ceff100e34b8539b0eb4c3c Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Tue, 14 Jul 2009 15:09:39 -0700 Subject: [PATCH] Support ptracing of fork'd children. R=rsc APPROVED=rsc DELTA=26 (22 added, 1 deleted, 3 changed) OCL=31613 CL=31629 --- src/pkg/syscall/exec.go | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/pkg/syscall/exec.go b/src/pkg/syscall/exec.go index 58fb058635..3dd0727f81 100644 --- a/src/pkg/syscall/exec.go +++ b/src/pkg/syscall/exec.go @@ -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, -- 2.48.1