X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Ftrace_writer_local.cpp;h=5aeedac520febb823ad08e86aa10bd30a05a24ca;hb=8ecded8401d50cc3e8cc980243a016758550d950;hp=d03e1aefc141e26bdb00c7bf56a1487ecf010678;hpb=559d5349e8039871ff14509a26c54c980c8e2cc7;p=apitrace diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index d03e1ae..5aeedac 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -31,8 +31,10 @@ #include #include "os.hpp" +#include "os_thread.hpp" +#include "os_string.hpp" #include "trace_file.hpp" -#include "trace_writer.hpp" +#include "trace_writer_local.hpp" #include "trace_format.hpp" @@ -73,32 +75,37 @@ LocalWriter::~LocalWriter() void LocalWriter::open(void) { + os::String szFileName; - static unsigned dwCounter = 0; - - const char *szExtension = "trace"; - char szFileName[PATH_MAX]; const char *lpFileName; lpFileName = getenv("TRACE_FILE"); - if (lpFileName) { - strncpy(szFileName, lpFileName, PATH_MAX); - } - else { - char szProcessName[PATH_MAX]; - char szCurrentDir[PATH_MAX]; - os::getProcessName(szProcessName, PATH_MAX); - os::getCurrentDir(szCurrentDir, PATH_MAX); + if (!lpFileName) { + static unsigned dwCounter = 0; + + os::String process = os::getProcessName(); +#ifdef _WIN32 + process.trimExtension(); +#endif + process.trimDirectory(); + +#ifdef ANDROID + os::String prefix = "/data"; +#else + os::String prefix = os::getCurrentDir(); +#endif + prefix.join(process); for (;;) { FILE *file; if (dwCounter) - snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension); + szFileName = os::String::format("%s.%u.trace", prefix.str(), dwCounter); else - snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension); + szFileName = os::String::format("%s.trace", prefix.str()); - file = fopen(szFileName, "rb"); + lpFileName = szFileName; + file = fopen(lpFileName, "rb"); if (file == NULL) break; @@ -108,9 +115,12 @@ LocalWriter::open(void) { } } - os::log("apitrace: tracing to %s\n", szFileName); + os::log("apitrace: tracing to %s\n", lpFileName); - Writer::open(szFileName); + if (!Writer::open(lpFileName)) { + os::log("apitrace: error: failed to open %s\n", lpFileName); + os::abort(); + } #if 0 // For debugging the exception handler @@ -118,25 +128,39 @@ LocalWriter::open(void) { #endif } +static unsigned next_thread_id = 0; +static os::thread_specific_ptr thread_id_specific_ptr; + unsigned LocalWriter::beginEnter(const FunctionSig *sig) { - os::acquireMutex(); + mutex.lock(); ++acquired; if (!m_file->isOpened()) { open(); } - return Writer::beginEnter(sig); + unsigned *thread_id_ptr = thread_id_specific_ptr.get(); + unsigned thread_id; + if (thread_id_ptr) { + thread_id = *thread_id_ptr; + } else { + thread_id = next_thread_id++; + thread_id_ptr = new unsigned; + *thread_id_ptr = thread_id; + thread_id_specific_ptr.reset(thread_id_ptr); + } + + return Writer::beginEnter(sig, thread_id); } void LocalWriter::endEnter(void) { Writer::endEnter(); --acquired; - os::releaseMutex(); + mutex.unlock(); } void LocalWriter::beginLeave(unsigned call) { - os::acquireMutex(); + mutex.lock(); ++acquired; Writer::beginLeave(call); } @@ -144,23 +168,28 @@ void LocalWriter::beginLeave(unsigned call) { void LocalWriter::endLeave(void) { Writer::endLeave(); --acquired; - os::releaseMutex(); + mutex.unlock(); } void LocalWriter::flush(void) { /* * Do nothing if the mutex is already acquired (e.g., if a segfault happen - * while writing the file) to prevent dead-lock. + * while writing the file) as state could be inconsistent, therefore yield + * inconsistent trace files and/or repeated segfaults till infinity. */ - if (!acquired) { - os::acquireMutex(); + mutex.lock(); + if (acquired) { + os::log("apitrace: ignoring exception while tracing\n"); + } else { + ++acquired; if (m_file->isOpened()) { os::log("apitrace: flushing trace due to an exception\n"); m_file->flush(); } - os::releaseMutex(); + --acquired; } + mutex.unlock(); }