OSDN Git Service

atrace: add the 'dalvik' trace category
[android-x86/frameworks-native.git] / cmds / atrace / atrace.cpp
index 29838e4..1911839 100644 (file)
@@ -42,6 +42,7 @@ using namespace android;
 enum { MAX_SYS_FILES = 8 };
 
 const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
+const char* k_traceAppCmdlineProperty = "debug.atrace.app_cmdlines";
 
 typedef enum { OPT, REQ } requiredness  ;
 
@@ -79,6 +80,8 @@ static const TracingCategory k_categories[] = {
     { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
     { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
     { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
+    { "res",        "Resource Loading", ATRACE_TAG_RESOURCES, { } },
+    { "dalvik",     "Dalvik VM",        ATRACE_TAG_DALVIK, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
@@ -118,6 +121,7 @@ static bool g_compress = false;
 static bool g_nohup = false;
 static int g_initialSleepSecs = 0;
 static const char* g_kernelTraceFuncs = NULL;
+static const char* g_debugAppCmdLine = "";
 
 /* Global state */
 static bool g_traceAborted = false;
@@ -176,13 +180,18 @@ static bool fileIsWritable(const char* filename) {
 // Truncate a file.
 static bool truncateFile(const char* path)
 {
-    int err = truncate(path, 0);
-    if (err != 0) {
+    // This uses creat rather than truncate because some of the debug kernel
+    // device nodes (e.g. k_ftraceFilterPath) currently aren't changed by
+    // calls to truncate, but they are cleared by calls to creat.
+    int traceFD = creat(path, 0);
+    if (traceFD == -1) {
         fprintf(stderr, "error truncating %s: %s (%d)\n", path,
-                strerror(errno), errno);
+            strerror(errno), errno);
         return false;
     }
 
+    close(traceFD);
+
     return true;
 }
 
@@ -360,7 +369,18 @@ static bool setTagsProperty(uint64_t tags)
         fprintf(stderr, "error setting trace tags system property\n");
         return false;
     }
-    return pokeBinderServices();
+    return true;
+}
+
+// Set the system property that indicates which apps should perform
+// application-level tracing.
+static bool setAppCmdlineProperty(const char* cmdline)
+{
+    if (property_set(k_traceAppCmdlineProperty, cmdline) < 0) {
+        fprintf(stderr, "error setting trace app system property\n");
+        return false;
+    }
+    return true;
 }
 
 // Disable all /sys/ enable files.
@@ -428,8 +448,10 @@ static bool setKernelTraceFuncs(const char* funcs)
 
     if (funcs == NULL || funcs[0] == '\0') {
         // Disable kernel function tracing.
-        ok &= writeStr(k_currentTracerPath, "nop");
-        if (fileExists(k_ftraceFilterPath)) {
+        if (fileIsWritable(k_currentTracerPath)) {
+            ok &= writeStr(k_currentTracerPath, "nop");
+        }
+        if (fileIsWritable(k_ftraceFilterPath)) {
             ok &= truncateFile(k_ftraceFilterPath);
         }
     } else {
@@ -481,6 +503,8 @@ static bool setUpTrace()
         }
     }
     ok &= setTagsProperty(tags);
+    ok &= setAppCmdlineProperty(g_debugAppCmdLine);
+    ok &= pokeBinderServices();
 
     // Disable all the sysfs enables.  This is done as a separate loop from
     // the enables to allow the same enable to exist in multiple categories.
@@ -514,8 +538,10 @@ static void cleanUpTrace()
     // Disable all tracing that we're able to.
     disableKernelTraceEvents();
 
-    // Disable all the trace tags.
+    // Reset the system properties.
     setTagsProperty(0);
+    setAppCmdlineProperty("");
+    pokeBinderServices();
 
     // Set the options back to their defaults.
     setTraceOverwriteEnable(true);
@@ -693,6 +719,8 @@ static void showHelp(const char *cmd)
 {
     fprintf(stderr, "usage: %s [options] [categories...]\n", cmd);
     fprintf(stderr, "options include:\n"
+                    "  -a appname      enable app-level tracing for a comma "
+                        "separated list of cmdlines\n"
                     "  -b N            use a trace buffer size of N KB\n"
                     "  -c              trace into a circular buffer\n"
                     "  -k fname,...    trace the listed kernel functions\n"
@@ -732,7 +760,7 @@ int main(int argc, char **argv)
             {           0,                0, 0,  0 }
         };
 
-        ret = getopt_long(argc, argv, "b:ck:ns:t:z",
+        ret = getopt_long(argc, argv, "a:b:ck:ns:t:z",
                           long_options, &option_index);
 
         if (ret < 0) {
@@ -746,6 +774,10 @@ int main(int argc, char **argv)
         }
 
         switch(ret) {
+            case 'a':
+                g_debugAppCmdLine = optarg;
+            break;
+
             case 'b':
                 g_traceBufferSizeKB = atoi(optarg);
             break;
@@ -756,11 +788,11 @@ int main(int argc, char **argv)
 
             case 'k':
                 g_kernelTraceFuncs = optarg;
-                break;
+            break;
 
             case 'n':
                 g_nohup = true;
-                break;
+            break;
 
             case 's':
                 g_initialSleepSecs = atoi(optarg);
@@ -791,7 +823,7 @@ int main(int argc, char **argv)
                     listSupportedCategories();
                     exit(0);
                 }
-                break;
+            break;
 
             default:
                 fprintf(stderr, "\n");