Skip to content

Commit 8dfdfa6

Browse files
committedJan 3, 2018
Hide some symbols to avoid a crash on shutdown when using code coverage
Summary: gcov / gcda-based profiling crashes when shared libraries are unloaded Patch by Benoit Belley and test by Marco Castelluccio for Firefox See https://bugs.llvm.org/show_bug.cgi?id=27224 & https://bugzilla.mozilla.org/show_bug.cgi?id=1401230 Reviewers: davidxl, rnk, void Subscribers: jessicah, marco-c, belleyb, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D38124 llvm-svn: 321703
1 parent ba3a619 commit 8dfdfa6

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed
 

‎compiler-rt/lib/profile/GCDAProfiling.c

+13
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ static void unmap_file() {
228228
* profiling enabled will emit to a different file. Only one file may be
229229
* started at a time.
230230
*/
231+
COMPILER_RT_VISIBILITY
231232
void llvm_gcda_start_file(const char *orig_filename, const char version[4],
232233
uint32_t checksum) {
233234
const char *mode = "r+b";
@@ -295,6 +296,7 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4],
295296
/* Given an array of pointers to counters (counters), increment the n-th one,
296297
* where we're also given a pointer to n (predecessor).
297298
*/
299+
COMPILER_RT_VISIBILITY
298300
void llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
299301
uint64_t **counters) {
300302
uint64_t *counter;
@@ -317,6 +319,7 @@ void llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
317319
#endif
318320
}
319321

322+
COMPILER_RT_VISIBILITY
320323
void llvm_gcda_emit_function(uint32_t ident, const char *function_name,
321324
uint32_t func_checksum, uint8_t use_extra_checksum,
322325
uint32_t cfg_checksum) {
@@ -343,6 +346,7 @@ void llvm_gcda_emit_function(uint32_t ident, const char *function_name,
343346
write_string(function_name);
344347
}
345348

349+
COMPILER_RT_VISIBILITY
346350
void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
347351
uint32_t i;
348352
uint64_t *old_ctrs = NULL;
@@ -394,6 +398,7 @@ void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
394398
#endif
395399
}
396400

401+
COMPILER_RT_VISIBILITY
397402
void llvm_gcda_summary_info() {
398403
const uint32_t obj_summary_len = 9; /* Length for gcov compatibility. */
399404
uint32_t i;
@@ -447,6 +452,7 @@ void llvm_gcda_summary_info() {
447452
#endif
448453
}
449454

455+
COMPILER_RT_VISIBILITY
450456
void llvm_gcda_end_file() {
451457
/* Write out EOF record. */
452458
if (output_file) {
@@ -472,6 +478,7 @@ void llvm_gcda_end_file() {
472478
#endif
473479
}
474480

481+
COMPILER_RT_VISIBILITY
475482
void llvm_register_writeout_function(writeout_fn fn) {
476483
struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node));
477484
new_node->fn = fn;
@@ -485,6 +492,7 @@ void llvm_register_writeout_function(writeout_fn fn) {
485492
}
486493
}
487494

495+
COMPILER_RT_VISIBILITY
488496
void llvm_writeout_files(void) {
489497
struct writeout_fn_node *curr = writeout_fn_head;
490498

@@ -494,6 +502,7 @@ void llvm_writeout_files(void) {
494502
}
495503
}
496504

505+
COMPILER_RT_VISIBILITY
497506
void llvm_delete_writeout_function_list(void) {
498507
while (writeout_fn_head) {
499508
struct writeout_fn_node *node = writeout_fn_head;
@@ -504,6 +513,7 @@ void llvm_delete_writeout_function_list(void) {
504513
writeout_fn_head = writeout_fn_tail = NULL;
505514
}
506515

516+
COMPILER_RT_VISIBILITY
507517
void llvm_register_flush_function(flush_fn fn) {
508518
struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node));
509519
new_node->fn = fn;
@@ -517,6 +527,7 @@ void llvm_register_flush_function(flush_fn fn) {
517527
}
518528
}
519529

530+
COMPILER_RT_VISIBILITY
520531
void __gcov_flush() {
521532
struct flush_fn_node *curr = flush_fn_head;
522533

@@ -526,6 +537,7 @@ void __gcov_flush() {
526537
}
527538
}
528539

540+
COMPILER_RT_VISIBILITY
529541
void llvm_delete_flush_function_list(void) {
530542
while (flush_fn_head) {
531543
struct flush_fn_node *node = flush_fn_head;
@@ -536,6 +548,7 @@ void llvm_delete_flush_function_list(void) {
536548
flush_fn_head = flush_fn_tail = NULL;
537549
}
538550

551+
COMPILER_RT_VISIBILITY
539552
void llvm_gcov_init(writeout_fn wfn, flush_fn ffn) {
540553
static int atexit_ran = 0;
541554

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <dlfcn.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
int main(int argc, char *argv[]) {
6+
dlerror();
7+
void *f1_handle = dlopen("func.shared", RTLD_LAZY | RTLD_GLOBAL);
8+
if (f1_handle == NULL) {
9+
fprintf(stderr, "unable to open 'func.shared': %s\n", dlerror());
10+
return EXIT_FAILURE;
11+
}
12+
13+
void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
14+
if (f2_handle == NULL) {
15+
fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
16+
return EXIT_FAILURE;
17+
}
18+
19+
if (dlclose(f2_handle) != 0) {
20+
fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
21+
return EXIT_FAILURE;
22+
}
23+
24+
return EXIT_SUCCESS;
25+
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
RUN: mkdir -p %t.d
2+
RUN: %clang --coverage -o %t.d/func.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func.c
3+
RUN: %clang --coverage -o %t.d/func2.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func2.c
4+
RUN: %clang --coverage -o %t -fPIC -rpath %t.d %S/Inputs/instrprof-dlopen-dlclose-main.c
5+
6+
RUN: %run %t

0 commit comments

Comments
 (0)
Please sign in to comment.