X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Ftrace_writer_local.cpp;h=c5a5c4447b2b4213bea2603f6fd905f554c67bca;hb=edea899194c441353943c22577bc22bf0e64d187;hp=b894bf9d095e775f86fee36f1bd648b55f04808d;hpb=aa1b2136cc72893e519ff73c47e2ecd29cafe1da;p=apitrace diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index b894bf9..c5a5c44 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -43,16 +43,16 @@ namespace trace { static const char *memcpy_args[3] = {"dest", "src", "n"}; -FunctionSig memcpy_sig = {0, "memcpy", 3, memcpy_args, false}; +const FunctionSig memcpy_sig = {0, "memcpy", 3, memcpy_args}; static const char *malloc_args[1] = {"size"}; -FunctionSig malloc_sig = {1, "malloc", 1, malloc_args, false}; +const FunctionSig malloc_sig = {1, "malloc", 1, malloc_args}; static const char *free_args[1] = {"ptr"}; -FunctionSig free_sig = {2, "free", 1, free_args, false}; +const FunctionSig free_sig = {2, "free", 1, free_args}; static const char *realloc_args[2] = {"ptr", "size"}; -FunctionSig realloc_sig = {3, "realloc", 2, realloc_args, false}; +const FunctionSig realloc_sig = {3, "realloc", 2, realloc_args}; static void exceptionCallback(void) @@ -64,6 +64,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); @@ -72,6 +74,7 @@ LocalWriter::LocalWriter() : LocalWriter::~LocalWriter() { os::resetExceptionCallback(); + checkProcessId(); } void @@ -123,6 +126,8 @@ LocalWriter::open(void) { os::abort(); } + pid = os::getCurrentProcessId(); + #if 0 // For debugging the exception handler *((int *)0) = 0; @@ -134,10 +139,25 @@ static uintptr_t next_thread_num = 1; static OS_THREAD_SPECIFIC_PTR(void) thread_num; -unsigned LocalWriter::beginEnter(FunctionSig *sig) { +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, bool fake) { mutex.lock(); ++acquired; + checkProcessId(); if (!m_file->isOpened()) { open(); } @@ -153,10 +173,12 @@ unsigned LocalWriter::beginEnter(FunctionSig *sig) { assert(this_thread_num); unsigned thread_id = this_thread_num - 1; unsigned call_no = Writer::beginEnter(sig, thread_id); - if (sig->backtrace) { + if (!fake && backtrace_is_needed(sig->name)) { std::vector backtrace = get_backtrace(); - beginBacktrace(); - writeBacktrace(backtrace); + beginBacktrace(backtrace.size()); + for (unsigned i = 0; i < backtrace.size(); ++i) { + writeStackFrame(&backtrace[i]); + } endBacktrace(); } return call_no; @@ -193,8 +215,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; }