[compiler-rt] 48c196f - [gcov] Move llvm_writeout_files from atexit to a static destructor

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 1 16:42:08 PDT 2020


Author: Fangrui Song
Date: 2020-07-01T16:41:55-07:00
New Revision: 48c196f5c8b339c347d0a4ecf944c942fa5df765

URL: https://github.com/llvm/llvm-project/commit/48c196f5c8b339c347d0a4ecf944c942fa5df765
DIFF: https://github.com/llvm/llvm-project/commit/48c196f5c8b339c347d0a4ecf944c942fa5df765.diff

LOG: [gcov] Move llvm_writeout_files from atexit to a static destructor

atexit registered functions run earlier so `__attribute__((destructor))`
annotated functions cannot be tracked.

Set a priority of 100 (compatible with GCC 7 onwards) to track
destructors and destructors whose priorities are greater than 100.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7970

Reviewed By: calixte, marco-c

Differential Revision: https://reviews.llvm.org/D82253

Added: 
    compiler-rt/test/profile/Posix/gcov-destructor.c

Modified: 
    compiler-rt/lib/profile/GCDAProfiling.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index d15540d7c18a..57d8dec423cc 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -628,8 +628,14 @@ void llvm_writeout_files(void) {
   }
 }
 
-COMPILER_RT_VISIBILITY
-void llvm_delete_writeout_function_list(void) {
+#ifndef _WIN32
+// __attribute__((destructor)) and destructors whose priorities are greater than
+// 100 run before this function and can thus be tracked. The priority is
+// compatible with GCC 7 onwards.
+__attribute__((destructor(100)))
+#endif
+static void llvm_writeout_and_clear(void) {
+  llvm_writeout_files();
   fn_list_remove(&writeout_fn_list);
 }
 
@@ -710,8 +716,9 @@ void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn, fn_ptr rfn) {
     /* Make sure we write out the data and delete the data structures. */
     atexit(llvm_delete_reset_function_list);
     atexit(llvm_delete_flush_function_list);
-    atexit(llvm_delete_writeout_function_list);
-    atexit(llvm_writeout_files);
+#ifdef _WIN32
+    atexit(llvm_writeout_and_clear);
+#endif
   }
 }
 

diff  --git a/compiler-rt/test/profile/Posix/gcov-destructor.c b/compiler-rt/test/profile/Posix/gcov-destructor.c
new file mode 100644
index 000000000000..33c2f574b5df
--- /dev/null
+++ b/compiler-rt/test/profile/Posix/gcov-destructor.c
@@ -0,0 +1,33 @@
+/// Test that destructors and destructors whose priorities are greater than 100 are tracked.
+// RUN: mkdir -p %t.dir && cd %t.dir
+// RUN: %clang --coverage %s -o %t
+// RUN: rm -f gcov-destructor.gcda && %run %t
+// RUN: llvm-cov gcov -t gcov-destructor.gcda | FileCheck %s
+
+#include <unistd.h>
+
+void before_exec() {}                   // CHECK:      1: [[#@LINE]]:void before_exec
+void after_exec() {}                    // CHECK-NEXT: 1: [[#@LINE]]:void after_exec
+
+__attribute__((constructor))            // CHECK:      -: [[#@LINE]]:__attribute__
+void constructor() {}                   // CHECK-NEXT: 1: [[#@LINE]]:
+
+/// Runs before __llvm_gcov_writeout.
+__attribute__((destructor))             // CHECK:      -: [[#@LINE]]:__attribute__
+void destructor() {}                    // CHECK-NEXT: 1: [[#@LINE]]:
+
+__attribute__((destructor(101)))        // CHECK:      -: [[#@LINE]]:__attribute__
+void destructor_101() {}                // CHECK-NEXT: 1: [[#@LINE]]:
+
+/// Runs after __llvm_gcov_writeout.
+__attribute__((destructor(99)))         // CHECK:      -: [[#@LINE]]:__attribute__
+void destructor_99() {}                 // CHECK-NEXT: #####: [[#@LINE]]:
+
+int main() {
+  before_exec();
+  // Implicit writeout.
+  execl("/not_exist", "not_exist", (char *)0);
+  // Still tracked.
+  after_exec();
+  return 0;
+}


        


More information about the llvm-commits mailing list