[libsanitizer] Use internal_fork() to spawn the symbolizer process.

This should fix https://code.google.com/p/thread-sanitizer/issues/detail?id=61

llvm-svn: 208707
This commit is contained in:
Alexander Potapenko 2014-05-13 16:17:54 +00:00
parent 8063c3b80c
commit 4a6cac4382
5 changed files with 44 additions and 1 deletions

View File

@ -91,6 +91,8 @@ uptr internal_waitpid(int pid, int *status, int options);
uptr internal_getpid();
uptr internal_getppid();
uptr internal_fork();
// Threading
uptr internal_sched_yield();

View File

@ -501,6 +501,10 @@ uptr internal_sigaltstack(const struct sigaltstack *ss,
return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
}
uptr internal_fork() {
return internal_syscall(SYSCALL(fork));
}
#if SANITIZER_LINUX
// Doesn't set sa_restorer, use with caution (see below).
int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {

View File

@ -126,6 +126,11 @@ int internal_sigaction(int signum, const void *act, void *oldact) {
(struct sigaction *)act, (struct sigaction *)oldact);
}
int internal_fork() {
// TODO(glider): this may call user's pthread_atfork() handlers which is bad.
return fork();
}
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
struct stat st;

View File

@ -234,7 +234,8 @@ class SymbolizerProcess : public ExternalSymbolizerInterface {
CHECK(infd);
CHECK(outfd);
int pid = fork();
// Real fork() may call user callbacks registered with pthread_atfork().
int pid = internal_fork();
if (pid == -1) {
// Fork() failed.
internal_close(infd[0]);

View File

@ -0,0 +1,31 @@
// RUN: %clang_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
// Regression test for
// https://code.google.com/p/thread-sanitizer/issues/detail?id=61
// When the data race was reported, pthread_atfork() handler used to be
// executed which caused another race report in the same thread, which resulted
// in a deadlock.
#include <pthread.h>
#include <stdio.h>
int glob = 0;
void *worker(void *unused) {
glob++;
return NULL;
}
void atfork() {
fprintf(stderr, "ATFORK\n");
glob++;
}
int main() {
pthread_atfork(atfork, NULL, NULL);
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
glob++;
pthread_join(t, NULL);
// CHECK: ThreadSanitizer: data race
// CHECK-NOT: ATFORK
return 0;
}