diff options
author | Pirama Arumuga Nainar <pirama@google.com> | 2019-06-03 10:56:35 -0700 |
---|---|---|
committer | Oliver Nguyen <olivernguyen@google.com> | 2020-01-27 15:45:09 -0800 |
commit | 2b1bdd1079b035c1023db310f31fe52793c8cd9c (patch) | |
tree | 1a6355405005a1ca7dd9d46abfca4759404c9b49 | |
parent | 999afeeb3e59b930f066cb0bb0402cd1b27d0805 (diff) | |
download | extras-2b1bdd1079b035c1023db310f31fe52793c8cd9c.tar.gz |
Do init_profile_extras constructor tasks only once
Bug: http://b/116873221
Currently, every coverage-enabled binary (the main executable or shared
library) in the process executes the init_profile_extras constructor
leading to redundant initialization.
Instead, add a weak global value that gets set once so following
constructors don't set a signal handler or create a pthread. It's ok to
do this before the constructor succeeds because if pthread creation or
signal handler registration failed once, they are unlikely to succeed
the second time.
This is thread-safe since constructor initialization is single-threaded.
The one possibility for a race - the process doesn't have any
coverage-enabled library, and multiple threads dlopen() coverage-enabled
shared libraries - seems quite unlikely.
Test: Verify that only one extra thread is created for a daemon (adbd).
Change-Id: Ie969311c2ddac147497c870b5c365b4617b3c60a
Merged-In: Ie969311c2ddac147497c870b5c365b4617b3c60a
(cherry picked from commit e76c23dc6b7bff0c7404744b9bdde0d02465acdf)
-rw-r--r-- | toolchain-extras/profile-extras.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/toolchain-extras/profile-extras.cpp b/toolchain-extras/profile-extras.cpp index 2d685084..f999a6b2 100644 --- a/toolchain-extras/profile-extras.cpp +++ b/toolchain-extras/profile-extras.cpp @@ -67,6 +67,8 @@ void *property_watch_loop(__unused void *arg) { } } +__attribute__((weak)) int init_profile_extras_once = 0; + // Initialize libprofile-extras: // - Install a signal handler that triggers __gcov_flush on <GCOV_FLUSH_SIGNAL>. // - Create a thread that calls __gcov_flush when <kCoveragePropName> sysprop @@ -81,6 +83,10 @@ void *property_watch_loop(__unused void *arg) { // We force the linker to include init_profile_extras() by passing // '-uinit_profile_extras' to the linker (in build/soong). __attribute__((constructor)) int init_profile_extras(void) { + if (init_profile_extras_once) + return 0; + init_profile_extras_once = 1; + sighandler_t ret1 = signal(GCOV_FLUSH_SIGNAL, gcov_signal_handler); if (ret1 == SIG_ERR) { return -1; |