forked from OSchip/llvm-project
[profile] Add llvm_gcov_flush to be called outside a shared library
__gcov_flush is hidden. For applications to dump profiling data of selected .so files, they can use dlsym to find and call llvm_gcov_flush in each .so file. Differential Revision: https://reviews.llvm.org/D45454 llvm-svn: 336019
This commit is contained in:
parent
5cc0e25324
commit
7222e8e30b
|
@ -527,6 +527,10 @@ void llvm_register_flush_function(flush_fn fn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// __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
|
COMPILER_RT_VISIBILITY
|
||||||
void __gcov_flush() {
|
void __gcov_flush() {
|
||||||
struct flush_fn_node *curr = flush_fn_head;
|
struct flush_fn_node *curr = flush_fn_head;
|
||||||
|
@ -537,6 +541,12 @@ void __gcov_flush() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// llvm_gcov_flush is not hidden for a program to use dlsym to
|
||||||
|
// find and call for any linked .so file.
|
||||||
|
void llvm_gcov_flush() {
|
||||||
|
__gcov_flush();
|
||||||
|
}
|
||||||
|
|
||||||
COMPILER_RT_VISIBILITY
|
COMPILER_RT_VISIBILITY
|
||||||
void llvm_delete_flush_function_list(void) {
|
void llvm_delete_flush_function_list(void) {
|
||||||
while (flush_fn_head) {
|
while (flush_fn_head) {
|
||||||
|
|
|
@ -10,12 +10,42 @@ int main(int argc, char *argv[]) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dlerror();
|
||||||
void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
|
void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (f2_handle == NULL) {
|
if (f2_handle == NULL) {
|
||||||
fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
|
fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dlerror();
|
||||||
|
void (*gcov_flush)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
|
||||||
|
if (gcov_flush != NULL || dlerror() == NULL) {
|
||||||
|
fprintf(stderr, "__gcov_flush should not be visible in func.shared'\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlerror();
|
||||||
|
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': %s\n", dlerror());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
f1_flush();
|
||||||
|
|
||||||
|
dlerror();
|
||||||
|
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': %s\n", dlerror());
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlerror();
|
||||||
if (dlclose(f2_handle) != 0) {
|
if (dlclose(f2_handle) != 0) {
|
||||||
fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
|
fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
Loading…
Reference in New Issue