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