diff options
| author | Calixte Denizet <calixte.denizet@gmail.com> | 2019-12-10 13:22:33 +0100 |
|---|---|---|
| committer | Calixte Denizet <calixte.denizet@gmail.com> | 2019-12-12 09:23:32 +0100 |
| commit | 02ce9d8ef5a84bc884de4105eae5f8736ef67634 (patch) | |
| tree | dd1e16637f564cacffaf849e5a015b2e3205762b /compiler-rt/lib | |
| parent | fa0fc04a4f950461e3f5675487b477c94e456842 (diff) | |
| download | bcm5719-llvm-02ce9d8ef5a84bc884de4105eae5f8736ef67634.tar.gz bcm5719-llvm-02ce9d8ef5a84bc884de4105eae5f8736ef67634.zip | |
[compiler-rt] Add a critical section when flushing gcov counters
Summary:
Counters can be flushed in a multi-threaded context for example when the process is forked in different threads (https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp#L632-L663).
In order to avoid pretty bad things, a critical section is needed around the flush.
We had a lot of crashes in this code in Firefox CI when we switched to clang for linux ccov builds and those crashes disappeared with this patch.
Reviewers: marco-c, froydnj, dmajor, davidxl, vsk
Reviewed By: marco-c, dmajor
Subscribers: ahatanak, froydnj, dmajor, dberris, jfb, #sanitizers, llvm-commits, sylvestre.ledru
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D70910
Diffstat (limited to 'compiler-rt/lib')
| -rw-r--r-- | compiler-rt/lib/profile/GCDAProfiling.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index 498c05900bf..81f2cdd2645 100644 --- a/compiler-rt/lib/profile/GCDAProfiling.c +++ b/compiler-rt/lib/profile/GCDAProfiling.c @@ -62,8 +62,27 @@ typedef unsigned long long uint64_t; #include "InstrProfiling.h" #include "InstrProfilingUtil.h" -/* #define DEBUG_GCDAPROFILING */ +#ifndef _WIN32 +#include <pthread.h> +static pthread_mutex_t gcov_flush_mutex = PTHREAD_MUTEX_INITIALIZER; +static __inline void gcov_flush_lock() { + pthread_mutex_lock(&gcov_flush_mutex); +} +static __inline void gcov_flush_unlock() { + pthread_mutex_unlock(&gcov_flush_mutex); +} +#else +#include <windows.h> +static SRWLOCK gcov_flush_mutex = SRWLOCK_INIT; +static __inline void gcov_flush_lock() { + AcquireSRWLockExclusive(&gcov_flush_mutex); +} +static __inline void gcov_flush_unlock() { + ReleaseSRWLockExclusive(&gcov_flush_mutex); +} +#endif +/* #define DEBUG_GCDAPROFILING */ /* * --- GCOV file format I/O primitives --- */ @@ -620,12 +639,16 @@ void llvm_register_flush_function(fn_ptr fn) { } void __gcov_flush() { + gcov_flush_lock(); + struct fn_node* curr = flush_fn_list.head; while (curr) { curr->fn(); curr = curr->next; } + + gcov_flush_unlock(); } COMPILER_RT_VISIBILITY |

