]> git.cworth.org Git - apitrace/commitdiff
Merge branch 'fork-safe' (issue #110)
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 10 May 2013 12:20:50 +0000 (13:20 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 10 May 2013 12:20:50 +0000 (13:20 +0100)
common/os_posix.cpp
common/os_process.hpp
common/trace_writer_local.cpp
common/trace_writer_local.hpp

index bd15bbac43db16710075fff3afaa59bf11e3e15c..5ec8b363390792748e733a6d8d5e7a9b3afadb24 100644 (file)
@@ -173,8 +173,16 @@ log(const char *format, ...)
 #ifdef ANDROID
     __android_log_vprint(ANDROID_LOG_DEBUG, "apitrace", format, ap);
 #else
-    vfprintf(stderr, format, ap);
-    fflush(stderr);
+    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;
index ba53408ccb8faa662df5d6f3ed021ce5e7d890f9..e1b1df17179e8457239e9b021d593b30d23eaac5 100644 (file)
@@ -33,6 +33,9 @@
 
 #ifdef _WIN32
 #include <windows.h>
+#else
+#include <sys/types.h>
+#include <unistd.h>
 #endif
 
 #include "os.hpp"
 namespace os {
 
 
-inline void
+typedef
+#ifdef _WIN32
+   DWORD
+#else
+   pid_t
+#endif
+ProcessId;
+
+
+static inline ProcessId
+getCurrentProcessId(void) {
+#ifdef _WIN32
+    return GetCurrentProcessId();
+#else
+    return getpid();
+#endif
+}
+
+
+static inline void
 setEnvironment(const char *name, const char *value) {
 #ifdef _WIN32
     SetEnvironmentVariableA(name, value);
@@ -51,7 +73,7 @@ setEnvironment(const char *name, const char *value) {
 }
 
 
-inline void
+static inline void
 unsetEnvironment(const char *name) {
 #ifdef _WIN32
     SetEnvironmentVariableA(name, NULL);
index 757e9c0fc328ce99dc94d9c7e33beaba1e49d158..d2ff3b5f73f2a41c5ea9c1413f98260a56941b20 100644 (file)
@@ -63,6 +63,8 @@ static void exceptionCallback(void)
 LocalWriter::LocalWriter() :
     acquired(0)
 {
+    os::log("apitrace: loaded\n");
+
     // Install the signal handlers as early as possible, to prevent
     // interfering with the application's signal handling.
     os::setExceptionCallback(exceptionCallback);
@@ -71,6 +73,7 @@ LocalWriter::LocalWriter() :
 LocalWriter::~LocalWriter()
 {
     os::resetExceptionCallback();
+    checkProcessId();
 }
 
 void
@@ -122,6 +125,8 @@ LocalWriter::open(void) {
         os::abort();
     }
 
+    pid = os::getCurrentProcessId();
+
 #if 0
     // For debugging the exception handler
     *((int *)0) = 0;
@@ -133,10 +138,25 @@ static uintptr_t next_thread_num = 1;
 static OS_THREAD_SPECIFIC_PTR(void)
 thread_num;
 
+void LocalWriter::checkProcessId(void) {
+    if (m_file->isOpened() &&
+        os::getCurrentProcessId() != pid) {
+        // We are a forked child process that inherited the trace file, so
+        // create a new file.  We can't call any method of the current
+        // file, as it may cause it to flush and corrupt the parent's
+        // trace, so we effectively leak the old file object.
+        m_file = File::createSnappy();
+        // Don't want to open the same file again
+        os::unsetEnvironment("TRACE_FILE");
+        open();
+    }
+}
+
 unsigned LocalWriter::beginEnter(const FunctionSig *sig) {
     mutex.lock();
     ++acquired;
 
+    checkProcessId();
     if (!m_file->isOpened()) {
         open();
     }
@@ -185,8 +205,12 @@ void LocalWriter::flush(void) {
     } else {
         ++acquired;
         if (m_file->isOpened()) {
-            os::log("apitrace: flushing trace due to an exception\n");
-            m_file->flush();
+            if (os::getCurrentProcessId() != pid) {
+                os::log("apitrace: ignoring exception in child process\n");
+            } else {
+                os::log("apitrace: flushing trace due to an exception\n");
+                m_file->flush();
+            }
         }
         --acquired;
     }
index cc5dda0115eb425e462d12203bbb2c2bc4e65cd1..815e3c0fe2ca55171ea6537826380f81d1bf899d 100644 (file)
@@ -34,6 +34,7 @@
 #include <stdint.h>
 
 #include "os_thread.hpp"
+#include "os_process.hpp"
 #include "trace_writer.hpp"
 
 
@@ -70,6 +71,13 @@ namespace trace {
         os::recursive_mutex mutex;
         int acquired;
 
+        /**
+         * ID of the processed that opened the trace file.
+         */
+        os::ProcessId pid;
+
+        void checkProcessId();
+
     public:
         /**
          * Should never called directly -- use localWriter singleton below