forked from OSchip/llvm-project
[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:
parent
8063c3b80c
commit
4a6cac4382
|
@ -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();
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue