Cut off process names for profiling.
/proc/<pid>/comm cannot be longer than 16 characters. Because of this,
packages starting with android.hardware.* etc.. are indistinguishable
between tool that use comm to identify processes. This makes using tools
like systrace extremely difficult and error prone.
Test: external/chromium-trace/systrace.py -b 32000 audio sched freq idle
workq irq binder_driver am sync hal app pm ss -t 5
Test: (sanity) hidl_test
Bug: 33664825
Change-Id: I4c9ba4d75b9ad1c1161335fe3595e13ac3222bb6
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index d7a2edc..0e56d18 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -19,6 +19,8 @@
#include <condition_variable>
#include <dlfcn.h>
#include <dirent.h>
+#include <fstream>
+#include <pthread.h>
#include <unistd.h>
#include <mutex>
@@ -66,13 +68,74 @@
}
}
-sp<IServiceManager> defaultServiceManager() {
+bool endsWith(const std::string &in, const std::string &suffix) {
+ return in.size() >= suffix.size() &&
+ in.substr(in.size() - suffix.size()) == suffix;
+}
+bool startsWith(const std::string &in, const std::string &prefix) {
+ return in.size() >= prefix.size() &&
+ in.substr(0, prefix.size()) == prefix;
+}
+
+std::string binaryName() {
+ std::ifstream ifs("/proc/self/cmdline");
+ std::string cmdline;
+ if (!ifs.is_open()) {
+ return "";
+ }
+ ifs >> cmdline;
+
+ size_t idx = cmdline.rfind("/");
+ if (idx != std::string::npos) {
+ cmdline = cmdline.substr(idx + 1);
+ }
+
+ return cmdline;
+}
+
+void tryShortenProcessName(const std::string &packageName) {
+ std::string processName = binaryName();
+
+ if (!startsWith(processName, packageName)) {
+ return;
+ }
+
+ // e.x. android.hardware.module.foo@1.0 -> foo@1.0
+ size_t lastDot = packageName.rfind('.');
+ size_t secondDot = packageName.rfind('.', lastDot - 1);
+
+ if (secondDot == std::string::npos) {
+ return;
+ }
+
+ std::string newName = processName.substr(secondDot + 1,
+ 16 /* TASK_COMM_LEN */ - 1);
+ ALOGI("Removing namespace from process name %s to %s.",
+ processName.c_str(), newName.c_str());
+
+ int rc = pthread_setname_np(pthread_self(), newName.c_str());
+ ALOGI_IF(rc != 0, "Removing namespace from process name %s failed.",
+ processName.c_str());
+}
+
+namespace details {
+
+void onRegistration(const std::string &packageName,
+ const std::string& /* interfaceName */,
+ const std::string& /* instanceName */) {
+ tryShortenProcessName(packageName);
+}
+
+} // details
+
+sp<IServiceManager> defaultServiceManager() {
{
AutoMutex _l(details::gDefaultServiceManagerLock);
if (details::gDefaultServiceManager != NULL) {
return details::gDefaultServiceManager;
}
+
if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
// HwBinder not available on this device or not accessible to
// this process.
@@ -95,16 +158,6 @@
return details::gDefaultServiceManager;
}
-bool endsWith(const std::string &in, const std::string &suffix) {
- return in.size() >= suffix.size() &&
- in.substr(in.size() - suffix.size()) == suffix;
-}
-
-bool startsWith(const std::string &in, const std::string &prefix) {
- return in.size() >= prefix.size() &&
- in.substr(0, prefix.size()) == prefix;
-}
-
std::vector<std::string> search(const std::string &path,
const std::string &prefix,
const std::string &suffix) {