Index: lib/profile/GCDAProfiling.c =================================================================== --- lib/profile/GCDAProfiling.c +++ lib/profile/GCDAProfiling.c @@ -527,6 +527,10 @@ } } +// __gcov_flush is hidden. When called in a .so file, +// it dumps profile data of the calling .so file. +// If a main program needs to dump profile data of each linked +// .so files, it should use dlsym to find and call llvm_gcov_flush. COMPILER_RT_VISIBILITY void __gcov_flush() { struct flush_fn_node *curr = flush_fn_head; @@ -537,6 +541,14 @@ } } +// llvm_gcov_flush is not hidden for a program to use dlsym to +// find and call. In that case, it dumps profile data of a .so file. +// If it is called directly inside a .so file, the unified copy of +// llvm_gcov_flush might dump data of other .so file or the main module. +void llvm_gcov_flush() { + __gcov_flush(); +} + COMPILER_RT_VISIBILITY void llvm_delete_flush_function_list(void) { while (flush_fn_head) { Index: test/profile/Inputs/instrprof-dlopen-dlclose-main.c =================================================================== --- test/profile/Inputs/instrprof-dlopen-dlclose-main.c +++ test/profile/Inputs/instrprof-dlopen-dlclose-main.c @@ -16,6 +16,31 @@ return EXIT_FAILURE; } + void (*gcov_flush)() = (void (*)())dlsym(f1_handle, "__gcov_flush"); + if (gcov_flush != NULL) { + fprintf(stderr, "__gcov_flush should not be visible in func.shared'\n"); + return EXIT_FAILURE; + } + + void (*f1_flush)() = (void (*)())dlsym(f1_handle, "llvm_gcov_flush"); + if (f1_flush == NULL) { + fprintf(stderr, "unable to find llvm_gcov_flush in func.shared'\n"); + return EXIT_FAILURE; + } + f1_flush(); + + void (*f2_flush)() = (void (*)())dlsym(f2_handle, "llvm_gcov_flush"); + if (f2_flush == NULL) { + fprintf(stderr, "unable to find llvm_gcov_flush in func2.shared'\n"); + return EXIT_FAILURE; + } + f2_flush(); + + if (f1_flush == f2_flush) { + fprintf(stderr, "Same llvm_gcov_flush found in func.shared and func2.shared\n"); + return EXIT_FAILURE; + } + if (dlclose(f2_handle) != 0) { fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror()); return EXIT_FAILURE;