[PATCH v3 08/18] Android: add support for dynamically enable/disable tracing

Imre Deak imre.deak at intel.com
Wed May 23 02:05:22 PDT 2012


To trace applications started by the Dalvik VM we have to wrap the main
Dalvik process zygote (or app_process) which is started at boot time and
never stopped afterwards. We would still want to restrict tracing to a
single process which will be forked by zygote.

To achieve this we'll use the fact that the forked process image is
contained in the same file as zygote, pointed to by /proc/self/exe. So
if this is 'app_process' we know it's a zygote process. To distinguish
between zygote processes we'll check /proc/self/cmdline which will in
turn be set to a unique application specific string (for example
com.android.settings). The user has to set the debug.apitrace.procname
to this string in order to enable tracing.

For non-zygote processes tracing will be always enabled.

Signed-off-by: Imre Deak <imre.deak at intel.com>
---
 common/os.hpp       |    9 +++++++
 common/os_posix.cpp |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 wrappers/trace.py   |    8 ++++++
 3 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/common/os.hpp b/common/os.hpp
index cc72a0e..7f62451 100644
--- a/common/os.hpp
+++ b/common/os.hpp
@@ -70,6 +70,15 @@ void log(const char *format, ...)
   #endif
 #endif
 
+#ifdef ANDROID
+bool apitrace_enabled(void);
+#else
+static inline bool apitrace_enabled(void)
+{
+    return true;
+}
+#endif
+
 void abort(void);
 
 void setExceptionCallback(void (*callback)(void));
diff --git a/common/os_posix.cpp b/common/os_posix.cpp
index 7d39d8a..d348ace 100644
--- a/common/os_posix.cpp
+++ b/common/os_posix.cpp
@@ -46,6 +46,10 @@
 
 #ifdef ANDROID
 #include <android/log.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/system_properties.h>
 #endif
 
 #ifndef PATH_MAX
@@ -97,6 +101,68 @@ getProcessName(void)
     return path;
 }
 
+#ifdef ANDROID
+static String
+getZygoteProcessName(void)
+{
+    String path;
+    size_t size = PATH_MAX;
+    char *buf = path.buf(size);
+    ssize_t len;
+
+    int fd = open("/proc/self/cmdline", O_RDONLY);
+
+    assert(fd >= 0);
+    len = read(fd, buf, size - 1);
+    close(fd);
+    path.truncate(len);
+
+    return path;
+}
+
+static bool isZygoteProcess(void)
+{
+    os::String proc_name;
+
+    proc_name = getProcessName();
+    proc_name.trimDirectory();
+
+    return strcmp(proc_name, "app_process") == 0;
+}
+
+bool apitrace_enabled(void)
+{
+    static pid_t cached_pid;
+    static bool enabled;
+    pid_t pid;
+
+    pid = getpid();
+    if (cached_pid == pid)
+        return enabled;
+    cached_pid = pid;
+
+    if (!isZygoteProcess()) {
+        os::log("apitrace[%d]: enabled for standalone %s", pid,
+                (const char *)proc_name);
+        enabled = true;
+        return true;
+    }
+
+    char target_proc_name[PROP_VALUE_MAX] = "";
+    os::String proc_name;
+
+    proc_name = getZygoteProcessName();
+    proc_name.trimDirectory();
+
+    __system_property_get("debug.apitrace.procname", target_proc_name);
+    enabled = !strcmp(target_proc_name, proc_name);
+    os::log("apitrace[%d]: %s for %s",
+            pid, enabled ? "enabled" : "disabled", (const char *)proc_name);
+
+    return enabled;
+}
+#endif
+
 String
 getCurrentDir(void)
 {
diff --git a/wrappers/trace.py b/wrappers/trace.py
index c838dc7..749aff3 100644
--- a/wrappers/trace.py
+++ b/wrappers/trace.py
@@ -422,6 +422,14 @@ class Tracer:
         print function.prototype() + ' {'
         if function.type is not stdapi.Void:
             print '    %s _result;' % function.type
+        print '    if (!os::apitrace_enabled()) {'
+        Tracer.invokeFunction(self, function)
+        if function.type is not stdapi.Void:
+            print '        return _result;'
+        else:
+            print '        return;'
+        print '    }'
+        print
         self.traceFunctionImplBody(function)
         if function.type is not stdapi.Void:
             print '    return _result;'
-- 
1.7.5.4



More information about the apitrace mailing list