Skip to content

Commit 88f5bf7

Browse files
committed
[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 Reviewed By: marco-c, dmajor Subscribers: froydnj, dmajor, dberris, jfb, #sanitizers, llvm-commits, sylvestre.ledru Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D70910
1 parent f6e0567 commit 88f5bf7

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

compiler-rt/lib/profile/GCDAProfiling.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,27 @@ typedef unsigned long long uint64_t;
6262
#include "InstrProfiling.h"
6363
#include "InstrProfilingUtil.h"
6464

65-
/* #define DEBUG_GCDAPROFILING */
65+
#ifndef _WIN32
66+
#include <pthread.h>
67+
pthread_mutex_t gcov_flush_mutex = PTHREAD_MUTEX_INITIALIZER;
68+
static __inline void gcov_flush_lock() {
69+
pthread_mutex_lock(&gcov_flush_mutex);
70+
}
71+
static __inline void gcov_flush_unlock() {
72+
pthread_mutex_unlock(&gcov_flush_mutex);
73+
}
74+
#else
75+
#include <windows.h>
76+
static SRWLOCK gcov_flush_mutex = SRWLOCK_INIT;
77+
static __inline void gcov_flush_lock() {
78+
AcquireSRWLockExclusive(&gcov_flush_mutex);
79+
}
80+
static __inline void gcov_flush_unlock() {
81+
ReleaseSRWLockExclusive(&gcov_flush_mutex);
82+
}
83+
#endif
6684

85+
/* #define DEBUG_GCDAPROFILING */
6786
/*
6887
* --- GCOV file format I/O primitives ---
6988
*/
@@ -620,12 +639,16 @@ void llvm_register_flush_function(fn_ptr fn) {
620639
}
621640

622641
void __gcov_flush() {
642+
gcov_flush_lock();
643+
623644
struct fn_node* curr = flush_fn_list.head;
624645

625646
while (curr) {
626647
curr->fn();
627648
curr = curr->next;
628649
}
650+
651+
gcov_flush_unlock();
629652
}
630653

631654
COMPILER_RT_VISIBILITY

0 commit comments

Comments
 (0)