diff options
| -rw-r--r-- | cmds/atrace/Android.mk | 4 | ||||
| -rw-r--r-- | cmds/atrace/atrace.c | 49 |
2 files changed, 37 insertions, 16 deletions
diff --git a/cmds/atrace/Android.mk b/cmds/atrace/Android.mk index 1de8e95c44..12526d0235 100644 --- a/cmds/atrace/Android.mk +++ b/cmds/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/cmds/atrace/atrace.c b/cmds/atrace/atrace.c index a0d42502c0..d81cb5c0c6 100644 --- a/cmds/atrace/atrace.c +++ b/cmds/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) { |