Support gcov flushing in libhidlbase.
am: 21d59d923d
Change-Id: Ia303085cb786093af4d6c20c62b9cb5928682fc1
diff --git a/base/HidlInternal.cpp b/base/HidlInternal.cpp
index b41c0b9..64b4f26 100644
--- a/base/HidlInternal.cpp
+++ b/base/HidlInternal.cpp
@@ -24,10 +24,14 @@
#ifdef LIBHIDL_TARGET_DEBUGGABLE
#include <dirent.h>
#include <dlfcn.h>
-#include <regex>
+#include <link.h>
#include <utils/misc.h>
+#include <regex>
extern "C" __attribute__((weak)) void __sanitizer_cov_dump();
+const char* kSysPropHalCoverage = "hal.coverage.enable";
+const char* kGcovPrefixEnvVar = "GCOV_PREFIX";
+const char* kGcovPrefixPath = "/data/misc/trace/";
#endif
namespace android {
@@ -49,13 +53,41 @@
if (__sanitizer_cov_dump != nullptr) {
::android::add_sysprop_change_callback(
[]() {
- bool enableCoverage = property_get_bool("hal.coverage.enable", false);
+ bool enableCoverage = property_get_bool(kSysPropHalCoverage, false);
if (enableCoverage) {
__sanitizer_cov_dump();
}
},
0);
}
+ if (property_get_bool("ro.vts.coverage", false)) {
+ const std::string gcovPath = kGcovPrefixPath + std::to_string(getpid());
+ setenv(kGcovPrefixEnvVar, gcovPath.c_str(), true /* overwrite */);
+ ::android::add_sysprop_change_callback(
+ []() {
+ const bool enableCoverage = property_get_bool(kSysPropHalCoverage, false);
+ if (enableCoverage) {
+ dl_iterate_phdr(
+ [](struct dl_phdr_info* info, size_t /* size */, void* /* data */) {
+ if (strlen(info->dlpi_name) == 0) return 0;
+
+ void* handle = dlopen(info->dlpi_name, RTLD_LAZY);
+ if (handle == nullptr) {
+ LOG(INFO) << "coverage dlopen failed: " << dlerror();
+ return 0;
+ }
+ void (*flush)() = (void (*)())dlsym(handle, "__gcov_flush");
+ if (flush == nullptr) {
+ return 0;
+ }
+ flush();
+ return 0;
+ },
+ nullptr /* data */);
+ }
+ },
+ 0 /* priority */);
+ }
#endif
}