mirror of
https://github.com/golang/go.git
synced 2025-05-17 13:24:38 +00:00
Support ptracing of fork'd children.
R=rsc APPROVED=rsc DELTA=26 (22 added, 1 deleted, 3 changed) OCL=31613 CL=31629
This commit is contained in:
parent
40f406afc4
commit
14bb806cb4
@ -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 [
|
|||||||
|
|
||||||
// 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:
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user