Commit 63e0ddc7 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

cmd/gc: do not race instrument syscall.forkAndExecInChild

Race instrumentation can allocate, switch stacks, preempt, etc.
All that is not allowed in between fork and exec.
Fixes #4840.

R=golang-dev, daniel.morsing, dave
CC=golang-dev
https://golang.org/cl/11324044
parent 7e270cf6
......@@ -51,6 +51,18 @@ ispkgin(const char **pkgs, int n)
return 0;
}
static int
isforkfunc(Node *fn)
{
// Special case for syscall.forkAndExecInChild.
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// Race instrumentation does all of the above.
return myimportpath != nil && strcmp(myimportpath, "syscall") == 0 &&
strcmp(fn->nname->sym->name, "forkAndExecInChild") == 0;
}
void
racewalk(Node *fn)
{
......@@ -58,7 +70,7 @@ racewalk(Node *fn)
Node *nodpc;
char s[1024];
if(ispkgin(omit_pkgs, nelem(omit_pkgs)))
if(ispkgin(omit_pkgs, nelem(omit_pkgs)) || isforkfunc(fn))
return;
if(!ispkgin(noinst_pkgs, nelem(noinst_pkgs))) {
......
......@@ -27,6 +27,7 @@ type SysProcAttr struct {
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// For the same reason compiler does not race instrument it.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
......
......@@ -28,6 +28,7 @@ type SysProcAttr struct {
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// For the same reason compiler does not race instrument it.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
......
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