summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Essick <essick@google.com>2020-01-09 11:51:27 -0800
committerOliver Nguyen <olivernguyen@google.com>2020-02-03 19:05:39 +0000
commit572460c417e6e0fd9337e5ef6507335d6d40d42b (patch)
tree188cf180b036603889e0b35286c83f1917e71c56
parent466d7164cf077377a82c2e598613373ed9cf590b (diff)
downloadextras-572460c417e6e0fd9337e5ef6507335d6d40d42b.tar.gz
Dump coverage for all objects (a.out + dlopen()'d .so's)
with code coverage enabled, the main object as well as each dlopen()ed shared library include their own copies of the hooks for dumping gcov data upon receiving signal GCOV_FLUSH_SIGNAL. Only the last one to register was actually dumped. Here, we chain the signal handlers together so that each one will call the previously registered handler to ensure that each object's coverage data is dumped. Bug: 139313557 Test: dump gcov data via kill -37 on module with dlopen() Change-Id: I376df2df6b65acff95ad5d135a7ba2bf0eac3695 Merged-In: I376df2df6b65acff95ad5d135a7ba2bf0eac3695 (cherry picked from commit b5d273da8824e8dd4bf9c28c50797364b0b47a05)
-rw-r--r--toolchain-extras/profile-extras.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/toolchain-extras/profile-extras.cpp b/toolchain-extras/profile-extras.cpp
index b7a9318a..7d78a0a5 100644
--- a/toolchain-extras/profile-extras.cpp
+++ b/toolchain-extras/profile-extras.cpp
@@ -31,8 +31,16 @@ extern "C" {
void __gcov_flush(void);
-static void gcov_signal_handler(__unused int signum) {
+// storing SIG_ERR helps us detect (unlikely) looping.
+static sighandler_t chained_gcov_signal_handler = SIG_ERR;
+
+static void gcov_signal_handler(int signum) {
__gcov_flush();
+ if (chained_gcov_signal_handler != SIG_ERR &&
+ chained_gcov_signal_handler != SIG_IGN &&
+ chained_gcov_signal_handler != SIG_DFL) {
+ (chained_gcov_signal_handler)(signum);
+ }
}
static const char kCoveragePropName[] = "debug.coverage.flush";
@@ -101,10 +109,15 @@ __attribute__((constructor)) int init_profile_extras(void) {
return 0;
init_profile_extras_once = 1;
+ // is this instance already registered?
+ if (chained_gcov_signal_handler != SIG_ERR) {
+ return -1;
+ }
sighandler_t ret1 = signal(GCOV_FLUSH_SIGNAL, gcov_signal_handler);
if (ret1 == SIG_ERR) {
return -1;
}
+ chained_gcov_signal_handler = ret1;
// Do not create thread running property_watch_loop for zygote (it can get
// invoked as zygote or app_process). This check is only needed for the