Index: lib/sanitizer_common/sanitizer_coverage_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -109,6 +109,8 @@ uptr *data(); uptr size(); + uptr *stack() const { return pc_stack; } + private: void DirectOpen(); void UpdateModuleNameVec(uptr caller_pc, uptr range_beg, uptr range_end); @@ -133,6 +135,8 @@ // Descriptor of the file mapped pc array. fd_t pc_fd; + uptr *pc_stack; + // Vector of coverage guard arrays, protected by mu. InternalMmapVectorNoCtor guard_array_vec; @@ -209,6 +213,9 @@ atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed); } + pc_stack = reinterpret_cast( + MmapNoReserveOrDie(sizeof(uptr) * kPcArrayMaxSize, "CovInit::pc_stack")); + cc_array = reinterpret_cast(MmapNoReserveOrDie( sizeof(uptr *) * kCcArrayMaxSize, "CovInit::cc_array")); atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed); @@ -246,6 +253,10 @@ UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize); cc_array = nullptr; } + if (pc_stack) { + UnmapOrDie(pc_stack, sizeof(uptr) * kPcArrayMaxSize); + pc_stack = nullptr; + } if (tr_event_array) { UnmapOrDie(tr_event_array, sizeof(tr_event_array[0]) * kTrEventArrayMaxSize + @@ -410,10 +421,12 @@ uptr idx = -guard_value - 1; if (idx >= atomic_load(&pc_array_index, memory_order_acquire)) return; // May happen after fork when pc_array_index becomes 0. + CHECK_LT(idx * sizeof(uptr), atomic_load(&pc_array_size, memory_order_acquire)); uptr counter = atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed); pc_array[idx] = BundlePcAndCounter(pc, counter); + pc_stack[counter] = pc; } // Registers a pair caller=>callee. @@ -942,6 +955,10 @@ *data = coverage_data.data(); return coverage_data.size(); } +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_get_coverage_stack(uptr **data) { + *data = coverage_data.stack(); +} SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_number_of_counters() {