#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);
}
-inline void
+static inline void
unsetEnvironment(const char *name) {
#ifdef _WIN32
SetEnvironmentVariableA(name, NULL);
os::abort();
}
+ pid = os::getCurrentProcessId();
+
#if 0
// For debugging the exception handler
*((int *)0) = 0;
if (!m_file->isOpened()) {
open();
+ } else {
+ if (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();
+ }
}
// Although thread_num is a void *, we actually use it as a uintptr_t
}
void LocalWriter::flush(void) {
+ if (os::getCurrentProcessId() != pid) {
+ os::log("apitrace: ignoring exception in child process\n");
+ return;
+ }
+
/*
* Do nothing if the mutex is already acquired (e.g., if a segfault happen
* while writing the file) as state could be inconsistent, therefore yield
#include <stdint.h>
#include "os_thread.hpp"
+#include "os_process.hpp"
#include "trace_writer.hpp"
os::recursive_mutex mutex;
int acquired;
+ /**
+ * ID of the processed that opened the trace file.
+ */
+ os::ProcessId pid;
+
public:
/**
* Should never called directly -- use localWriter singleton below