From 0f53d9a2ee556992aaa822fb21da66ca41539ffb Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Sat, 3 Jan 2015 02:07:58 +0000 Subject: [PATCH] [asan/tracing] extend the test a bit more, simplify the tracing code, add a guard page to trace array, fix the trace IDs before dumping llvm-svn: 225108 --- .../sanitizer_common/sanitizer_coverage_libcdep.cc | 25 ++++++++++++------- .../test/asan/TestCases/Linux/coverage-tracing.cc | 28 ++++++++++++---------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc index 0639dc0..2a6b4d1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -165,9 +165,12 @@ void CoverageData::Init() { atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed); atomic_store(&cc_array_index, 0, memory_order_relaxed); - tr_event_array = reinterpret_cast( - MmapNoReserveOrDie(sizeof(tr_event_array[0]) * kTrEventArrayMaxSize, - "CovInit::tr_event_array")); + // Allocate tr_event_array with a guard page at the end. + tr_event_array = reinterpret_cast(MmapNoReserveOrDie( + sizeof(tr_event_array[0]) * kTrEventArrayMaxSize + GetMmapGranularity(), + "CovInit::tr_event_array")); + Mprotect(reinterpret_cast(&tr_event_array[kTrEventArrayMaxSize]), + GetMmapGranularity()); tr_event_array_size = kTrEventArrayMaxSize; tr_event_array_index = 0; } @@ -416,6 +419,8 @@ void CoverageData::DumpTrace() { fd = CovOpenFile(false, "trace-events"); if (fd < 0) return; + for (uptr i = 0; i < max_idx; i++) + tr_event_array[i]--; // Fix the IDs. internal_write(fd, tr_event_array, max_idx * sizeof(tr_event_array[0])); internal_close(fd); VReport(1, " CovDump: Trace: %zd PCs written\n", size()); @@ -464,12 +469,16 @@ void CoverageData::DumpCallerCalleePairs() { // Record the current PC into the event buffer. // Every event is a u32 value (index in tr_pc_array_index) so we compute // it once and then cache in the provided 'cache' storage. +// +// This function will eventually be inlined by the compiler. void CoverageData::TraceBasicBlock(s32 *id) { - CHECK(coverage_enabled); - uptr idx = *id; - CHECK_LT(tr_event_array_index, tr_event_array_size); - tr_event_array[tr_event_array_index] = static_cast(idx); - tr_event_array_index++; + // CHECK(coverage_enabled); + // CHECK_LT(tr_event_array_index, tr_event_array_size); + // + // Will trap here if + // 1. coverage is not enabled at run-time. + // 2. The array tr_event_array is full. + tr_event_array[tr_event_array_index++] = static_cast(*id); } static void CovDumpAsBitSet() { diff --git a/compiler-rt/test/asan/TestCases/Linux/coverage-tracing.cc b/compiler-rt/test/asan/TestCases/Linux/coverage-tracing.cc index f696fb4..49dbb5e 100644 --- a/compiler-rt/test/asan/TestCases/Linux/coverage-tracing.cc +++ b/compiler-rt/test/asan/TestCases/Linux/coverage-tracing.cc @@ -4,14 +4,14 @@ // RUN: rm -rf %T/coverage-tracing // RUN: mkdir %T/coverage-tracing // RUN: cd %T/coverage-tracing -// RUN: A=x; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points -// RUN: A=f; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points -// RUN: A=b; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points -// RUN: A=bf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points -// RUN: A=fb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points -// RUN: A=ffb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points -// RUN: A=fff; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points -// RUN: A=bbf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points +// RUN: A=x; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points +// RUN: A=f; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points +// RUN: A=b; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points +// RUN: A=bf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points +// RUN: A=fb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points +// RUN: A=ffb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points +// RUN: A=fff; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points +// RUN: A=bbf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points // RUN: diff f.points fff.points // RUN: diff bf.points fb.points // RUN: diff bf.points ffb.points @@ -32,10 +32,13 @@ __attribute__((noinline)) void foo() { sink++; } __attribute__((noinline)) void bar() { sink++; } int main(int argc, char **argv) { - if (argc != 2) return 0; - for (int i = 0; argv[1][i]; i++) { - if (argv[1][i] == 'f') foo(); - else if (argv[1][i] == 'b') bar(); + if (argc != 3) return 0; + int n = strtol(argv[2], 0, 10); + while (n-- > 0) { + for (int i = 0; argv[1][i]; i++) { + if (argv[1][i] == 'f') foo(); + else if (argv[1][i] == 'b') bar(); + } } } @@ -44,3 +47,4 @@ int main(int argc, char **argv) { // CHECK2: CovDump: Trace: 2 Events written // CHECK3: CovDump: Trace: 3 Events written // CHECK4: CovDump: Trace: 4 Events written +// CHECK301: CovDump: Trace: 301 Events written -- 2.7.4