[sanitizer] Implement internal_fork and internal_forkpty for OS X

On Linux, we have internal_fork that forks without invoking user's pthread_atfork handlers, which is important for spawning external symbolizers. Let's implement this for OS X as well (using __fork). This patch also adds internal_forkpty which re-implements forkpty and uses __fork in it as well.

Differential Revision: http://reviews.llvm.org/D14869

llvm-svn: 253666
This commit is contained in:
Kuba Brecka 2015-11-20 14:28:33 +00:00
parent e08533577f
commit 1f73ba6053
3 changed files with 26 additions and 3 deletions

View File

@ -52,6 +52,7 @@ extern char **environ;
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h>
#include <util.h>
namespace __sanitizer {
@ -147,9 +148,30 @@ uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
return sigprocmask(how, set, oldset);
}
// Doesn't call pthread_atfork() handlers.
extern "C" pid_t __fork(void);
int internal_fork() {
// TODO(glider): this may call user's pthread_atfork() handlers which is bad.
return fork();
return __fork();
}
int internal_forkpty(int *amaster) {
int master, slave;
if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1;
int pid = __fork();
if (pid == -1) {
close(master);
close(slave);
return -1;
}
if (pid == 0) {
close(master);
CHECK_EQ(login_tty(slave), 0);
} else {
*amaster = master;
close(slave);
}
return pid;
}
uptr internal_rename(const char *oldpath, const char *newpath) {

View File

@ -54,6 +54,7 @@ uptr internal_ptrace(int request, int pid, void *addr, void *data);
uptr internal_waitpid(int pid, int *status, int options);
int internal_fork();
int internal_forkpty(int *amaster);
// These functions call appropriate pthread_ functions directly, bypassing
// the interceptor. They are weak and may not be present in some tools.

View File

@ -75,7 +75,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
#if SANITIZER_MAC
fd_t fd = kInvalidFd;
// Use forkpty to disable buffering in the new terminal.
pid = forkpty(&fd, 0, 0, 0);
pid = internal_forkpty(&fd);
if (pid == -1) {
// forkpty() failed.
Report("WARNING: failed to fork external symbolizer (errno: %d)\n",