From 2e0cc860b7002600281ff69bf08b7e502a5cc27f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 9 May 2013 18:32:37 +0100 Subject: [PATCH] Try to be robust against fork. --- common/os_process.hpp | 26 ++++++++++++++++++++++++-- common/trace_writer_local.cpp | 18 ++++++++++++++++++ common/trace_writer_local.hpp | 6 ++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/common/os_process.hpp b/common/os_process.hpp index ba53408..e1b1df1 100644 --- a/common/os_process.hpp +++ b/common/os_process.hpp @@ -33,6 +33,9 @@ #ifdef _WIN32 #include +#else +#include +#include #endif #include "os.hpp" @@ -41,7 +44,26 @@ 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); diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index 757e9c0..a998193 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -122,6 +122,8 @@ LocalWriter::open(void) { os::abort(); } + pid = os::getCurrentProcessId(); + #if 0 // For debugging the exception handler *((int *)0) = 0; @@ -139,6 +141,17 @@ unsigned LocalWriter::beginEnter(const FunctionSig *sig) { 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 @@ -173,6 +186,11 @@ void LocalWriter::endLeave(void) { } 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 diff --git a/common/trace_writer_local.hpp b/common/trace_writer_local.hpp index cc5dda0..6e4abc4 100644 --- a/common/trace_writer_local.hpp +++ b/common/trace_writer_local.hpp @@ -34,6 +34,7 @@ #include #include "os_thread.hpp" +#include "os_process.hpp" #include "trace_writer.hpp" @@ -70,6 +71,11 @@ namespace trace { 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 -- 2.45.2