]> git.cworth.org Git - apitrace/blobdiff - common/os_posix.cpp
common: dump backtrace on signals
[apitrace] / common / os_posix.cpp
index e4de967b045fd67c3ff5837127a5ddc18ccf055a..5d6bffe5dcdab406a23624692b965e1d0730305b 100644 (file)
@@ -23,6 +23,7 @@
  *
  **************************************************************************/
 
+#ifndef _WIN32
 
 #include <assert.h>
 #include <string.h>
 
 #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
@@ -59,6 +56,7 @@
 
 #include "os.hpp"
 #include "os_string.hpp"
+#include "os_backtrace.hpp"
 
 
 namespace os {
@@ -75,25 +73,33 @@ getProcessName(void)
 #ifdef __APPLE__
     uint32_t len = size;
     if (_NSGetExecutablePath(buf, &len) != 0) {
-        *buf = 0;
-        return path;
+        // grow buf and retry
+        buf = path.buf(len);
+        _NSGetExecutablePath(buf, &len);
     }
     len = strlen(buf);
 #else
     ssize_t len;
     len = readlink("/proc/self/exe", buf, size - 1);
-    if (len == -1) {
+    if (len <= 0) {
         // /proc/self/exe is not available on setuid processes, so fallback to
         // /proc/self/cmdline.
         int fd = open("/proc/self/cmdline", O_RDONLY);
         if (fd >= 0) {
-            len = read(fd, buf, size - 1);
+            // buf already includes trailing zero
+            len = read(fd, buf, size);
             close(fd);
+            if (len >= 0) {
+                len = strlen(buf);
+            }
         }
     }
     if (len <= 0) {
-        snprintf(buf, size, "%i", (int)getpid());
-        return path;
+        // fallback to process ID
+        len = snprintf(buf, size, "%i", (int)getpid());
+        if (len >= size) {
+            len = size - 1;
+        }
     }
 #endif
     path.truncate(len);
@@ -101,68 +107,6 @@ 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 *)getProcessName());
-        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)
 {
@@ -177,6 +121,12 @@ getCurrentDir(void)
     return path;
 }
 
+bool
+createDirectory(const String &path)
+{
+    return mkdir(path, 0777) == 0;
+}
+
 bool
 String::exists(void) const
 {
@@ -188,9 +138,6 @@ String::exists(void) const
         return false;
     }
 
-    if (!S_ISREG(st.st_mode))
-        return false;
-
     return true;
 }
 
@@ -200,7 +147,11 @@ int execute(char * const * args)
     if (pid == 0) {
         // child
         execvp(args[0], args);
-        fprintf(stderr, "error: failed to execute %s\n", args[0]);
+        fprintf(stderr, "error: failed to execute:");
+        for (unsigned i = 0; args[i]; ++i) {
+            fprintf(stderr, " %s", args[i]);
+        }
+        fprintf(stderr, "\n");
         exit(-1);
     } else {
         // parent
@@ -235,7 +186,16 @@ log(const char *format, ...)
 #ifdef ANDROID
     __android_log_vprint(ANDROID_LOG_DEBUG, "apitrace", format, ap);
 #else
-    vfprintf(stderr, format, ap);
+    static FILE *log = NULL;
+    if (!log) {
+        // Duplicate stderr file descriptor, to prevent applications from
+        // redirecting our debug messages to somewhere else.
+        //
+        // Another alternative would be to log to /dev/tty when available.
+        log = fdopen(dup(STDERR_FILENO), "at");
+    }
+    vfprintf(log, format, ap);
+    fflush(log);
 #endif
     va_end(ap);
     logging = false;
@@ -248,7 +208,7 @@ long long timeFrequency = 0LL;
 void
 abort(void)
 {
-    exit(0);
+    _exit(1);
 }
 
 
@@ -284,11 +244,11 @@ signalHandler(int sig, siginfo_t *info, void *context)
     if (recursion_count) {
         log("apitrace: warning: recursion handling signal %i\n", sig);
     } else {
-        if (gCallback) {
-            ++recursion_count;
+        ++recursion_count;
+        if (gCallback)
             gCallback();
-            --recursion_count;
-        }
+        os::dump_backtrace();
+        --recursion_count;
     }
 
     struct sigaction *old_action;
@@ -373,3 +333,4 @@ resetExceptionCallback(void)
 
 } /* namespace os */
 
+#endif // !defined(_WIN32)