summaryrefslogtreecommitdiffstats
path: root/libcutils/trace.c
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2013-02-25 18:15:40 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-03-28 20:59:31 +0000
commit774f9299912cdf9f2a6b3805bb557e30bafbad05 (patch)
tree6ab88f971e07d3048fdaa57ce7b59ee8d603b25c /libcutils/trace.c
parentde97f798a1c24303de35ff44e2f47b590b46a815 (diff)
downloadsystem_core-774f9299912cdf9f2a6b3805bb557e30bafbad05.zip
system_core-774f9299912cdf9f2a6b3805bb557e30bafbad05.tar.gz
system_core-774f9299912cdf9f2a6b3805bb557e30bafbad05.tar.bz2
libcutils: add support for app tracing
This change adds support for tracing using the ATRACE_TAG_APP tag. This tag is enabled only for processes in which the /proc/<pid>/cmdline value appears in the comma-separated list of such values in the debug.atrace.app_cmdlines system property. It is also only enabled if either the ro.debuggable system property is set to 1 or the application has declared itself debuggable in its manifest, which gets reported to libcutils by the framework. Change-Id: Ic94ba55f4e70a9cf994056acbf151e523428b65d
Diffstat (limited to 'libcutils/trace.c')
-rw-r--r--libcutils/trace.c90
1 files changed, 85 insertions, 5 deletions
diff --git a/libcutils/trace.c b/libcutils/trace.c
index 152ea61..047f889 100644
--- a/libcutils/trace.c
+++ b/libcutils/trace.c
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -29,11 +30,81 @@
#define LOG_TAG "cutils-trace"
#include <cutils/log.h>
-int32_t atrace_is_ready = 0;
-int atrace_marker_fd = -1;
-uint64_t atrace_enabled_tags = ATRACE_TAG_NOT_READY;
-static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT;
-static pthread_mutex_t atrace_tags_mutex = PTHREAD_MUTEX_INITIALIZER;
+int32_t atrace_is_ready = 0;
+int atrace_marker_fd = -1;
+uint64_t atrace_enabled_tags = ATRACE_TAG_NOT_READY;
+static bool atrace_is_debuggable = false;
+static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT;
+static pthread_mutex_t atrace_tags_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// Set whether this process is debuggable, which determines whether
+// application-level tracing is allowed when the ro.debuggable system property
+// is not set to '1'.
+void atrace_set_debuggable(bool debuggable)
+{
+ atrace_is_debuggable = debuggable;
+ atrace_update_tags();
+}
+
+// Check whether the given command line matches one of the comma-separated
+// values listed in the app_cmdlines property.
+static bool atrace_is_cmdline_match(const char* cmdline) {
+ char value[PROPERTY_VALUE_MAX];
+ char* start = value;
+
+ property_get("debug.atrace.app_cmdlines", value, "");
+
+ while (start != NULL) {
+ char* end = strchr(start, ',');
+
+ if (end != NULL) {
+ *end = '\0';
+ end++;
+ }
+
+ if (strcmp(cmdline, start) == 0) {
+ return true;
+ }
+
+ start = end;
+ }
+
+ return false;
+}
+
+// Determine whether application-level tracing is enabled for this process.
+static bool atrace_is_app_tracing_enabled()
+{
+ bool sys_debuggable = false;
+ bool proc_debuggable = false;
+ char value[PROPERTY_VALUE_MAX];
+ bool result = false;
+
+ // Check whether the system is debuggable.
+ property_get("ro.debuggable", value, "0");
+ if (value[0] == '1') {
+ sys_debuggable = true;
+ }
+
+ if (sys_debuggable || atrace_is_debuggable) {
+ // Check whether tracing is enabled for this process.
+ FILE * file = fopen("/proc/self/cmdline", "r");
+ if (file) {
+ char cmdline[4096];
+ if (fgets(cmdline, sizeof(cmdline), file)) {
+ result = atrace_is_cmdline_match(cmdline);
+ } else {
+ ALOGE("Error reading cmdline: %s (%d)", strerror(errno), errno);
+ }
+ fclose(file);
+ } else {
+ ALOGE("Error opening /proc/self/cmdline: %s (%d)", strerror(errno),
+ errno);
+ }
+ }
+
+ return result;
+}
// Read the sysprop and return the value tags should be set to
static uint64_t atrace_get_property()
@@ -52,6 +123,15 @@ static uint64_t atrace_get_property()
ALOGE("Error parsing trace property: Number too large: %s", value);
return 0;
}
+
+ // Only set the "app" tag if this process was selected for app-level debug
+ // tracing.
+ if (atrace_is_app_tracing_enabled()) {
+ tags |= ATRACE_TAG_APP;
+ } else {
+ tags &= ~ATRACE_TAG_APP;
+ }
+
return (tags | ATRACE_TAG_ALWAYS) & ATRACE_TAG_VALID_MASK;
}