[compiler-rt] r210180 - [sancov] Handle fork.

Kostya Serebryany kcc at google.com
Wed Dec 24 09:47:48 PST 2014


On Wed, Dec 24, 2014 at 1:42 AM, Evgeniy Stepanov <eugeni.stepanov at gmail.com
> wrote:
>
> It's a question of post-processing, right? These PCs are registered in
> the parent process's coverage dump.
>
> Well, yes. Iff you want to analyse the tree of processes as a whole, it's
enough.
I broke this yesterday (r224789)...


>
> On Tue, Dec 23, 2014 at 10:34 PM, Kostya Serebryany <kcc at google.com>
> wrote:
> > But it doesn't work!
> > Your code in ReInit changes the storage for counters but ti does not
> flush
> > the guards.
> >
> > On Tue, Dec 23, 2014 at 12:58 AM, Evgeniy Stepanov
> > <eugeni.stepanov at gmail.com> wrote:
> >>
> >> This is the main mode of execution on Android.
> >> And in Chromium.
> >> Better keep it.
> >>
> >>
> >> On Tue, Dec 23, 2014 at 1:53 AM, Kostya Serebryany <kcc at google.com>
> wrote:
> >> > I've stumbled upon this test while changing how the coverage logic
> >> > works...
> >> > Do we need coverage to work after fork but before exec at all?
> >> > It actually doesn't fully work today either, but I want to break it
> even
> >> > more...
> >> >
> >> > On Wed, Jun 4, 2014 at 5:13 AM, Evgeniy Stepanov
> >> > <eugeni.stepanov at gmail.com>
> >> > wrote:
> >> >>
> >> >> Author: eugenis
> >> >> Date: Wed Jun  4 07:13:54 2014
> >> >> New Revision: 210180
> >> >>
> >> >> URL: http://llvm.org/viewvc/llvm-project?rev=210180&view=rev
> >> >> Log:
> >> >> [sancov] Handle fork.
> >> >>
> >> >> Reset coverage data on fork().
> >> >> For memory-mapped mode (coverage_direct=1) this helps avoid loss of
> >> >> data
> >> >> (before this change two processes would write to the same file
> >> >> simultaneously).
> >> >> For normal mode, this reduces coverage dump size, because PCs from
> the
> >> >> parent
> >> >> process are no longer inherited by the child.
> >> >>
> >> >> Added:
> >> >>
>  compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc
> >> >> (with props)
> >> >>     compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc
> >> >> (with
> >> >> props)
> >> >> Modified:
> >> >>     compiler-rt/trunk/lib/asan/asan_interceptors.cc
> >> >>     compiler-rt/trunk/lib/asan/asan_interceptors.h
> >> >>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> >> >>
> >> >> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> >> >>
> >> >>
> >> >>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> >> >>
> >> >> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=210180&r1=210179&r2=210180&view=diff
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
> >> >> +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Jun  4
> 07:13:54
> >> >> 2014
> >> >> @@ -697,6 +697,16 @@ INTERCEPTOR(int, __cxa_atexit, void (*fu
> >> >>  }
> >> >>  #endif  // ASAN_INTERCEPT___CXA_ATEXIT
> >> >>
> >> >> +#if ASAN_INTERCEPT_FORK
> >> >> +INTERCEPTOR(int, fork, void) {
> >> >> +  ENSURE_ASAN_INITED();
> >> >> +  if (common_flags()->coverage) CovBeforeFork();
> >> >> +  int pid = REAL(fork)();
> >> >> +  if (common_flags()->coverage) CovAfterFork(pid);
> >> >> +  return pid;
> >> >> +}
> >> >> +#endif  // ASAN_INTERCEPT_FORK
> >> >> +
> >> >>  #if SANITIZER_WINDOWS
> >> >>  INTERCEPTOR_WINAPI(DWORD, CreateThread,
> >> >>                     void* security, uptr stack_size,
> >> >> @@ -808,6 +818,10 @@ void InitializeAsanInterceptors() {
> >> >>    ASAN_INTERCEPT_FUNC(__cxa_atexit);
> >> >>  #endif
> >> >>
> >> >> +#if ASAN_INTERCEPT_FORK
> >> >> +  ASAN_INTERCEPT_FUNC(fork);
> >> >> +#endif
> >> >> +
> >> >>    // Some Windows-specific interceptors.
> >> >>  #if SANITIZER_WINDOWS
> >> >>    InitializeWindowsInterceptors();
> >> >>
> >> >> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=210180&r1=210179&r2=210180&view=diff
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> --- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
> >> >> +++ compiler-rt/trunk/lib/asan/asan_interceptors.h Wed Jun  4
> 07:13:54
> >> >> 2014
> >> >> @@ -27,6 +27,7 @@
> >> >>  # define ASAN_INTERCEPT_INDEX 1
> >> >>  # define ASAN_INTERCEPT_PTHREAD_CREATE 1
> >> >>  # define ASAN_INTERCEPT_MLOCKX 1
> >> >> +# define ASAN_INTERCEPT_FORK 1
> >> >>  #else
> >> >>  # define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
> >> >>  # define ASAN_INTERCEPT__LONGJMP 0
> >> >> @@ -34,6 +35,7 @@
> >> >>  # define ASAN_INTERCEPT_INDEX 0
> >> >>  # define ASAN_INTERCEPT_PTHREAD_CREATE 0
> >> >>  # define ASAN_INTERCEPT_MLOCKX 0
> >> >> +# define ASAN_INTERCEPT_FORK 0
> >> >>  #endif
> >> >>
> >> >>  #if SANITIZER_FREEBSD || SANITIZER_LINUX
> >> >>
> >> >> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=210180&r1=210179&r2=210180&view=diff
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> >> >> (original)
> >> >> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Jun
> >> >> 4
> >> >> 07:13:54 2014
> >> >> @@ -193,6 +193,8 @@ void CovPrepareForSandboxing(__sanitizer
> >> >>  void SetSandboxingCallback(void (*f)());
> >> >>
> >> >>  void CovUpdateMapping();
> >> >> +void CovBeforeFork();
> >> >> +void CovAfterFork(int child_pid);
> >> >>
> >> >>  void InitTlsSize();
> >> >>  uptr GetTlsSize();
> >> >>
> >> >> Modified:
> >> >> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=210180&r1=210179&r2=210180&view=diff
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> ---
> >> >> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> >> >> (original)
> >> >> +++
> >> >> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> >> >> Wed Jun  4 07:13:54 2014
> >> >> @@ -59,6 +59,8 @@ namespace __sanitizer {
> >> >>  class CoverageData {
> >> >>   public:
> >> >>    void Init();
> >> >> +  void BeforeFork();
> >> >> +  void AfterFork(int child_pid);
> >> >>    void Extend(uptr npcs);
> >> >>    void Add(uptr pc);
> >> >>
> >> >> @@ -86,6 +88,7 @@ class CoverageData {
> >> >>    StaticSpinMutex mu;
> >> >>
> >> >>    void DirectOpen();
> >> >> +  void ReInit();
> >> >>  };
> >> >>
> >> >>  static CoverageData coverage_data;
> >> >> @@ -107,23 +110,47 @@ void CoverageData::DirectOpen() {
> >> >>  void CoverageData::Init() {
> >> >>    pc_array = reinterpret_cast<uptr *>(
> >> >>        MmapNoReserveOrDie(sizeof(uptr) * kPcArrayMaxSize,
> "CovInit"));
> >> >> +  pc_fd = kInvalidFd;
> >> >>    if (common_flags()->coverage_direct) {
> >> >>      atomic_store(&pc_array_size, 0, memory_order_relaxed);
> >> >>      atomic_store(&pc_array_index, 0, memory_order_relaxed);
> >> >>    } else {
> >> >> -    pc_fd = 0;
> >> >>      atomic_store(&pc_array_size, kPcArrayMaxSize,
> >> >> memory_order_relaxed);
> >> >>      atomic_store(&pc_array_index, 0, memory_order_relaxed);
> >> >>    }
> >> >>  }
> >> >>
> >> >> +void CoverageData::ReInit() {
> >> >> +  internal_munmap(pc_array, sizeof(uptr) * kPcArrayMaxSize);
> >> >> +  if (pc_fd != kInvalidFd) internal_close(pc_fd);
> >> >> +  if (common_flags()->coverage_direct) {
> >> >> +    // In memory-mapped mode we must extend the new file to the
> known
> >> >> array
> >> >> +    // size.
> >> >> +    uptr size = atomic_load(&pc_array_size, memory_order_relaxed);
> >> >> +    Init();
> >> >> +    if (size) Extend(size);
> >> >> +  } else {
> >> >> +    Init();
> >> >> +  }
> >> >> +}
> >> >> +
> >> >> +void CoverageData::BeforeFork() {
> >> >> +  mu.Lock();
> >> >> +}
> >> >> +
> >> >> +void CoverageData::AfterFork(int child_pid) {
> >> >> +  // We are single-threaded so it's OK to release the lock early.
> >> >> +  mu.Unlock();
> >> >> +  if (child_pid == 0) ReInit();
> >> >> +}
> >> >> +
> >> >>  // Extend coverage PC array to fit additional npcs elements.
> >> >>  void CoverageData::Extend(uptr npcs) {
> >> >>    if (!common_flags()->coverage_direct) return;
> >> >>    SpinMutexLock l(&mu);
> >> >>
> >> >> -  if (!pc_fd) DirectOpen();
> >> >> -  CHECK(pc_fd);
> >> >> +  if (pc_fd == kInvalidFd) DirectOpen();
> >> >> +  CHECK_NE(pc_fd, kInvalidFd);
> >> >>
> >> >>    uptr size = atomic_load(&pc_array_size, memory_order_relaxed);
> >> >>    size += npcs * sizeof(uptr);
> >> >> @@ -324,6 +351,15 @@ int MaybeOpenCovFile(const char *name) {
> >> >>    if (!common_flags()->coverage) return -1;
> >> >>    return CovOpenFile(true /* packed */, name);
> >> >>  }
> >> >> +
> >> >> +void CovBeforeFork() {
> >> >> +  coverage_data.BeforeFork();
> >> >> +}
> >> >> +
> >> >> +void CovAfterFork(int child_pid) {
> >> >> +  coverage_data.AfterFork(child_pid);
> >> >> +}
> >> >> +
> >> >>  }  // namespace __sanitizer
> >> >>
> >> >>  extern "C" {
> >> >>
> >> >> Modified:
> >> >>
> >> >>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc?rev=210180&r1=210179&r2=210180&view=diff
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> ---
> >> >>
> >> >>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> >> >> (original)
> >> >> +++
> >> >>
> >> >>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> >> >> Wed Jun  4 07:13:54 2014
> >> >> @@ -36,8 +36,27 @@
> >> >>  namespace __sanitizer {
> >> >>
> >> >>  static const uptr kMaxNumberOfModules = 1 << 14;
> >> >> +static const uptr kMaxTextSize = 64 * 1024;
> >> >>
> >> >> -static char *last_mapping;
> >> >> +struct CachedMapping {
> >> >> + public:
> >> >> +  bool TestAndUpdate(const char *new_mapping) {
> >> >> +    int new_pid = internal_getpid();
> >> >> +    if (last_mapping && last_pid == new_pid &&
> >> >> +        internal_strcmp(last_mapping, new_mapping) == 0)
> >> >> +      return false;
> >> >> +    if (!last_mapping) last_mapping = (char
> >> >> *)InternalAlloc(kMaxTextSize);
> >> >> +    last_pid = new_pid;
> >> >> +    internal_strncpy(last_mapping, new_mapping, kMaxTextSize);
> >> >> +    return true;
> >> >> +  }
> >> >> +
> >> >> + private:
> >> >> +  char *last_mapping;
> >> >> +  int last_pid;
> >> >> +};
> >> >> +
> >> >> +static CachedMapping cached_mapping;
> >> >>  static StaticSpinMutex mapping_mu;
> >> >>
> >> >>  void CovUpdateMapping() {
> >> >> @@ -45,7 +64,6 @@ void CovUpdateMapping() {
> >> >>
> >> >>    SpinMutexLock l(&mapping_mu);
> >> >>
> >> >> -  const uptr kMaxTextSize = 64 * 1024;
> >> >>    InternalScopedString text(kMaxTextSize);
> >> >>    InternalScopedBuffer<char> modules_data(kMaxNumberOfModules *
> >> >>                                            sizeof(LoadedModule));
> >> >> @@ -66,9 +84,8 @@ void CovUpdateMapping() {
> >> >>    }
> >> >>
> >> >>    // Do not write mapping if it is the same as the one we've wrote
> >> >> last
> >> >> time.
> >> >> -  if (last_mapping && (internal_strcmp(last_mapping, text.data()) ==
> >> >> 0))
> >> >> return;
> >> >> -  if (!last_mapping) last_mapping = (char
> >> >> *)InternalAlloc(kMaxTextSize);
> >> >> -  internal_strncpy(last_mapping, text.data(), kMaxTextSize);
> >> >> +  if (!cached_mapping.TestAndUpdate(text.data()))
> >> >> +    return;
> >> >>
> >> >>    int err;
> >> >>    InternalScopedString tmp_path(64 +
> >> >>
> >> >> Added:
> >> >> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc?rev=210180&view=auto
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> ---
> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc
> >> >> (added)
> >> >> +++
> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc
> >> >> Wed Jun  4 07:13:54 2014
> >> >> @@ -0,0 +1,38 @@
> >> >> +// RUN: %clangxx_asan -mllvm -asan-coverage=1 %s -o %t
> >> >> +// RUN: rm -rf %T/coverage-fork-direct
> >> >> +// RUN: mkdir -p %T/coverage-fork-direct && cd
> %T/coverage-fork-direct
> >> >> +// RUN: (ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run
> >> >> %t; \
> >> >> +// RUN:  %sancov rawunpack *.sancov.raw; %sancov print *.sancov)
> 2>&1
> >> >> +//
> >> >> +// XFAIL: android
> >> >> +
> >> >> +#include <stdio.h>
> >> >> +#include <string.h>
> >> >> +#include <unistd.h>
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void foo() { printf("foo\n"); }
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void bar() { printf("bar\n"); }
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void baz() { printf("baz\n"); }
> >> >> +
> >> >> +int main(int argc, char **argv) {
> >> >> +  pid_t child_pid = fork();
> >> >> +  if (child_pid == 0) {
> >> >> +    fprintf(stderr, "Child PID: %d\n", getpid());
> >> >> +    baz();
> >> >> +  } else {
> >> >> +    fprintf(stderr, "Parent PID: %d\n", getpid());
> >> >> +    foo();
> >> >> +    bar();
> >> >> +  }
> >> >> +  return 0;
> >> >> +}
> >> >> +
> >> >> +// CHECK-DAG: Child PID: [[ChildPID:[0-9]+]]
> >> >> +// CHECK-DAG: Parent PID: [[ParentPID:[0-9]+]]
> >> >> +// CHECK-DAG: read 3 PCs from {{.*}}.[[ParentPID]].sancov
> >> >> +// CHECK-DAG: read 1 PCs from {{.*}}.[[ChildPID]].sancov
> >> >>
> >> >> Propchange:
> >> >> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork-direct.cc
> >> >>
> >> >>
> >> >>
> ------------------------------------------------------------------------------
> >> >>     svn:eol-style = LF
> >> >>
> >> >> Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc
> >> >> URL:
> >> >>
> >> >>
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc?rev=210180&view=auto
> >> >>
> >> >>
> >> >>
> ==============================================================================
> >> >> --- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc
> >> >> (added)
> >> >> +++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc Wed
> >> >> Jun
> >> >> 4 07:13:54 2014
> >> >> @@ -0,0 +1,38 @@
> >> >> +// RUN: %clangxx_asan -mllvm -asan-coverage=1 %s -o %t
> >> >> +// RUN: export ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1
> >> >> +// RUN: rm -rf %T/coverage-fork
> >> >> +// RUN: mkdir -p %T/coverage-fork && cd %T/coverage-fork
> >> >> +// RUN: %run %t 2>&1 | FileCheck %s
> >> >> +//
> >> >> +// XFAIL: android
> >> >> +
> >> >> +#include <stdio.h>
> >> >> +#include <string.h>
> >> >> +#include <unistd.h>
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void foo() { printf("foo\n"); }
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void bar() { printf("bar\n"); }
> >> >> +
> >> >> +__attribute__((noinline))
> >> >> +void baz() { printf("baz\n"); }
> >> >> +
> >> >> +int main(int argc, char **argv) {
> >> >> +  pid_t child_pid = fork();
> >> >> +  if (child_pid == 0) {
> >> >> +    fprintf(stderr, "Child PID: %d\n", getpid());
> >> >> +    baz();
> >> >> +  } else {
> >> >> +    fprintf(stderr, "Parent PID: %d\n", getpid());
> >> >> +    foo();
> >> >> +    bar();
> >> >> +  }
> >> >> +  return 0;
> >> >> +}
> >> >> +
> >> >> +// CHECK-DAG: Child PID: [[ChildPID:[0-9]+]]
> >> >> +// CHECK-DAG: [[ChildPID]].sancov: 1 PCs written
> >> >> +// CHECK-DAG: Parent PID: [[ParentPID:[0-9]+]]
> >> >> +// CHECK-DAG: [[ParentPID]].sancov: 3 PCs written
> >> >>
> >> >> Propchange:
> >> >> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-fork.cc
> >> >>
> >> >>
> >> >>
> ------------------------------------------------------------------------------
> >> >>     svn:eol-style = LF
> >> >>
> >> >>
> >> >> _______________________________________________
> >> >> llvm-commits mailing list
> >> >> llvm-commits at cs.uiuc.edu
> >> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141224/17b6a9e4/attachment.html>


More information about the llvm-commits mailing list