summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/atrace/Android.mk4
-rw-r--r--cmds/atrace/atrace.c49
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) {