proc: bugfix: proc.Launch race (OS X)

This commit is contained in:
aarzilli 2015-11-18 13:08:53 +01:00
parent 5441135668
commit 2f9f20188a
3 changed files with 20 additions and 1 deletions

@ -15,6 +15,12 @@ fork_exec(char *argv0, char **argv, int size,
int fd[2]; int fd[2];
if (pipe(fd) < 0) return -1; if (pipe(fd) < 0) return -1;
// Create another pipe so that we know when we're about to exec. This ensures that control only returns
// back to Go-land when we call exec, effectively eliminating a race condition between launching the new
// process and trying to read its memory.
int wfd[2];
if (pipe(wfd) < 0) return -1;
kern_return_t kret; kern_return_t kret;
pid_t pid = fork(); pid_t pid = fork();
if (pid > 0) { if (pid > 0) {
@ -26,6 +32,11 @@ fork_exec(char *argv0, char **argv, int size,
char msg = 'c'; char msg = 'c';
write(fd[1], &msg, 1); write(fd[1], &msg, 1);
close(fd[1]); close(fd[1]);
char w;
read(wfd[0], &w, 1);
close(wfd[0]);
return pid; return pid;
} }
@ -53,6 +64,10 @@ fork_exec(char *argv0, char **argv, int size,
pret = ptrace(PT_SIGEXC, 0, 0, 0); pret = ptrace(PT_SIGEXC, 0, 0, 0);
if (pret != 0 && errno != 0) return -errno; if (pret != 0 && errno != 0) return -errno;
char msg = 'd';
write(wfd[1], &msg, 1);
close(wfd[1]);
// Create the child process. // Create the child process.
execve(argv0, argv, environ); execve(argv0, argv, environ);

@ -746,6 +746,10 @@ func (dbp *Process) getGoInformation() (ver GoVersion, isextld bool, err error)
err = fmt.Errorf("Could not determine version number: %v\n", err) err = fmt.Errorf("Could not determine version number: %v\n", err)
return return
} }
if vv.Unreadable != nil {
err = fmt.Errorf("Unreadable version number: %v\n", vv.Unreadable)
return
}
ver, ok := parseVersionString(constant.StringVal(vv.Value)) ver, ok := parseVersionString(constant.StringVal(vv.Value))
if !ok { if !ok {

@ -78,7 +78,7 @@ func Launch(cmd []string) (*Process, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = dbp.Continue() err = dbp.continueOnce()
return dbp, err return dbp, err
} }