[compiler-rt] r210180 - [sancov] Handle fork.
Kostya Serebryany
kcc at google.com
Tue Dec 30 15:19:08 PST 2014
I hope this is fixed now in r225016 (the guards are fully reinitialized
after fork)
Please check.
On Wed, Dec 24, 2014 at 9:47 AM, Kostya Serebryany <kcc at google.com> wrote:
>
>
> 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/20141230/179af4ae/attachment.html>
More information about the llvm-commits
mailing list