summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2012-06-07 16:27:03 -0700
committerJamie Gennis <jgennis@google.com>2012-06-07 17:52:34 -0700
commitb9314021ee1ccaa62eb115e8e0188f482a950f3b (patch)
treedb1823e417c1b7a14ba798f598e0634bed548789
parent83fdbb05c39b030ef1e5b3a7db79c617114c20f4 (diff)
downloadextras-b9314021ee1ccaa62eb115e8e0188f482a950f3b.tar.gz
atrace: enable running on user builds
This change allows atrace to be run on a user build, where it is not run as root. Some command line options still require root, and atrace will refuse to run if those options are specified when run as non-root. Bug: 6513400 Change-Id: I29984cb8a7c3ad80ba5fa6b031ed8ff81acabacf
-rw-r--r--atrace/Android.mk4
-rw-r--r--atrace/atrace.c49
2 files changed, 37 insertions, 16 deletions
diff --git a/atrace/Android.mk b/atrace/Android.mk
index 1de8e95c..12526d02 100644
--- a/atrace/Android.mk
+++ b/atrace/Android.mk
@@ -10,8 +10,8 @@ LOCAL_CFLAGS += -std=c99
LOCAL_MODULE:= atrace
-LOCAL_MODULE_TAGS:= debug
+LOCAL_MODULE_TAGS:= optional
-LOCAL_STATIC_LIBRARIES := libz
+LOCAL_SHARED_LIBRARIES := libz
include $(BUILD_EXECUTABLE)
diff --git a/atrace/atrace.c b/atrace/atrace.c
index a0d42502..d81cb5c0 100644
--- a/atrace/atrace.c
+++ b/atrace/atrace.c
@@ -55,6 +55,9 @@ static const char* k_tracingOverwriteEnablePath =
static const char* k_schedSwitchEnablePath =
"/sys/kernel/debug/tracing/events/sched/sched_switch/enable";
+static const char* k_schedWakeupEnablePath =
+ "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable";
+
static const char* k_cpuFreqEnablePath =
"/sys/kernel/debug/tracing/events/power/cpu_frequency/enable";
@@ -132,7 +135,10 @@ static bool setTraceOverwriteEnable(bool enable)
// Enable or disable tracing of the kernel scheduler switching.
static bool setSchedSwitchTracingEnable(bool enable)
{
- return setKernelOptionEnable(k_schedSwitchEnablePath, enable);
+ bool ok = true;
+ ok &= setKernelOptionEnable(k_schedSwitchEnablePath, enable);
+ ok &= setKernelOptionEnable(k_schedWakeupEnablePath, enable);
+ return ok;
}
// Enable or disable tracing of the CPU clock frequency.
@@ -212,11 +218,11 @@ static bool fileExists(const char* filename) {
}
// Enable tracing in the kernel.
-static bool startTrace()
+static bool startTrace(bool isRoot)
{
bool ok = true;
- // Set up the tracing options.
+ // Set up the tracing options that don't require root.
ok &= setTraceOverwriteEnable(g_traceOverwrite);
ok &= setSchedSwitchTracingEnable(g_traceSchedSwitch);
ok &= setCpuFrequencyTracingEnable(g_traceCpuFrequency);
@@ -224,11 +230,17 @@ static bool startTrace()
if (fileExists(k_governorLoadEnablePath) || g_traceGovernorLoad) {
ok &= setGovernorLoadTracingEnable(g_traceGovernorLoad);
}
- ok &= setWorkqueueTracingEnabled(g_traceWorkqueue);
- ok &= setDiskTracingEnabled(g_traceDisk);
ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
ok &= setGlobalClockEnable(true);
+ // Set up the tracing options that do require root. The options that
+ // require root should have errored out earlier if we're not running as
+ // root.
+ if (isRoot) {
+ ok &= setWorkqueueTracingEnabled(g_traceWorkqueue);
+ ok &= setDiskTracingEnabled(g_traceDisk);
+ }
+
// Enable tracing.
ok &= setTracingEnabled(true);
@@ -240,7 +252,7 @@ static bool startTrace()
}
// Disable tracing in the kernel.
-static void stopTrace()
+static void stopTrace(bool isRoot)
{
// Disable tracing.
setTracingEnabled(false);
@@ -252,9 +264,13 @@ static void stopTrace()
if (fileExists(k_governorLoadEnablePath)) {
setGovernorLoadTracingEnable(false);
}
- setWorkqueueTracingEnabled(false);
setGlobalClockEnable(false);
+ if (isRoot) {
+ setWorkqueueTracingEnabled(false);
+ setDiskTracingEnabled(false);
+ }
+
// Note that we can't reset the trace buffer size here because that would
// clear the trace before we've read it.
}
@@ -389,16 +405,13 @@ static void registerSigHandler() {
int main(int argc, char **argv)
{
+ bool isRoot = (getuid() == 0);
+
if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
showHelp(argv[0]);
exit(0);
}
- if (getuid() != 0) {
- fprintf(stderr, "error: %s must be run as root.", argv[0]);
- exit(1);
- }
-
for (;;) {
int ret;
@@ -426,6 +439,10 @@ int main(int argc, char **argv)
break;
case 'd':
+ if (!isRoot) {
+ fprintf(stderr, "error: tracing disk activity requires root privileges\n");
+ exit(1);
+ }
g_traceDisk = true;
break;
@@ -442,6 +459,10 @@ int main(int argc, char **argv)
break;
case 'w':
+ if (!isRoot) {
+ fprintf(stderr, "error: tracing kernel work queues requires root privileges\n");
+ exit(1);
+ }
g_traceWorkqueue = true;
break;
@@ -459,7 +480,7 @@ int main(int argc, char **argv)
registerSigHandler();
- bool ok = startTrace();
+ bool ok = startTrace(isRoot);
if (ok) {
printf("capturing trace...");
@@ -486,7 +507,7 @@ int main(int argc, char **argv)
}
// Stop the trace and restore the default settings.
- stopTrace();
+ stopTrace(isRoot);
if (ok) {
if (!g_traceAborted) {