X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=trace_writer.cpp;h=5a5f1f7d2400b13784fd9dedcc7421593c1e304f;hb=447f4a55a01e82b0265f44212b8d439fa83750d7;hp=a97cef25103e2882af4b0bdc6cfb87e51759ca87;hpb=9ed672278e79600c4c7ad34a715ecfc4beda9255;p=apitrace diff --git a/trace_writer.cpp b/trace_writer.cpp index a97cef2..5a5f1f7 100644 --- a/trace_writer.cpp +++ b/trace_writer.cpp @@ -30,81 +30,65 @@ #include #include -#include - -#include - #include "os.hpp" #include "trace_writer.hpp" +#include "trace_snappyfile.hpp" #include "trace_format.hpp" namespace Trace { -static gzFile g_gzFile = NULL; -static void _Close(void) { - if (g_gzFile != NULL) { - gzclose(g_gzFile); - g_gzFile = NULL; - } +Writer::Writer() : + call_no(0) +{ + m_file = new Trace::SnappyFile; + close(); } -static void _Open(const char *szExtension) { - _Close(); +Writer::~Writer() +{ + close(); + delete m_file; + m_file = NULL; +} - static unsigned dwCounter = 0; +void +Writer::close(void) { + m_file->close(); +} - char szFileName[PATH_MAX]; - const char *lpFileName; +bool +Writer::open(const char *filename) { + close(); - 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); - - for (;;) { - FILE *file; - - if (dwCounter) - snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension); - else - snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension); - - file = fopen(szFileName, "rb"); - if (file == NULL) - break; - - fclose(file); - - ++dwCounter; - } + if (!m_file->open(filename, File::Write)) { + return false; } - OS::DebugMessage("apitrace: tracing to %s\n", szFileName); + call_no = 0; + functions.clear(); + structs.clear(); + enums.clear(); + bitmasks.clear(); - g_gzFile = gzopen(szFileName, "wb"); -} + _writeUInt(TRACE_VERSION); -static inline void Write(const void *sBuffer, size_t dwBytesToWrite) { - if (g_gzFile == NULL) - return; + return true; +} - gzwrite(g_gzFile, sBuffer, dwBytesToWrite); +void inline +Writer::_write(const void *sBuffer, size_t dwBytesToWrite) { + m_file->write(sBuffer, dwBytesToWrite); } -static inline void -WriteByte(char c) { - Write(&c, 1); +void inline +Writer::_writeByte(char c) { + _write(&c, 1); } -void inline -WriteUInt(unsigned long long value) { +void inline +Writer::_writeUInt(unsigned long long value) { char buf[2 * sizeof value]; unsigned len; @@ -119,37 +103,28 @@ WriteUInt(unsigned long long value) { assert(len); buf[len - 1] &= 0x7f; - Write(buf, len); + _write(buf, len); } -static inline void -WriteFloat(float value) { +void inline +Writer::_writeFloat(float value) { assert(sizeof value == 4); - Write((const char *)&value, sizeof value); + _write((const char *)&value, sizeof value); } -static inline void -WriteDouble(double value) { +void inline +Writer::_writeDouble(double value) { assert(sizeof value == 8); - Write((const char *)&value, sizeof value); + _write((const char *)&value, sizeof value); } -static inline void -WriteString(const char *str) { +void inline +Writer::_writeString(const char *str) { size_t len = strlen(str); - WriteUInt(len); - Write(str, len); -} - -void Open(void) { - if (!g_gzFile) { - _Open("trace"); - WriteUInt(TRACE_VERSION); - } + _writeUInt(len); + _write(str, len); } -static unsigned call_no = 0; - inline bool lookup(std::vector &map, size_t index) { if (index >= map.size()) { map.resize(index + 1); @@ -159,224 +134,170 @@ inline bool lookup(std::vector &map, size_t index) { } } -static std::vector functions; -static std::vector structs; -static std::vector enums; -static std::vector bitmasks; - - -void Close(void) { - _Close(); - call_no = 0; - functions = std::vector(); - structs = std::vector(); - enums = std::vector(); - bitmasks = std::vector(); -} - -unsigned BeginEnter(const FunctionSig &function) { - OS::AcquireMutex(); - Open(); - WriteByte(Trace::EVENT_ENTER); - WriteUInt(function.id); - if (!lookup(functions, function.id)) { - WriteString(function.name); - WriteUInt(function.num_args); - for (unsigned i = 0; i < function.num_args; ++i) { - WriteString(function.args[i]); +unsigned Writer::beginEnter(const FunctionSig *sig) { + _writeByte(Trace::EVENT_ENTER); + _writeUInt(sig->id); + if (!lookup(functions, sig->id)) { + _writeString(sig->name); + _writeUInt(sig->num_args); + for (unsigned i = 0; i < sig->num_args; ++i) { + _writeString(sig->arg_names[i]); } - functions[function.id] = true; + functions[sig->id] = true; } + return call_no++; } -void EndEnter(void) { - WriteByte(Trace::CALL_END); - gzflush(g_gzFile, Z_SYNC_FLUSH); - OS::ReleaseMutex(); +void Writer::endEnter(void) { + _writeByte(Trace::CALL_END); } -void BeginLeave(unsigned call) { - OS::AcquireMutex(); - WriteByte(Trace::EVENT_LEAVE); - WriteUInt(call); +void Writer::beginLeave(unsigned call) { + _writeByte(Trace::EVENT_LEAVE); + _writeUInt(call); } -void EndLeave(void) { - WriteByte(Trace::CALL_END); - gzflush(g_gzFile, Z_SYNC_FLUSH); - OS::ReleaseMutex(); +void Writer::endLeave(void) { + _writeByte(Trace::CALL_END); } -void BeginArg(unsigned index) { - WriteByte(Trace::CALL_ARG); - WriteUInt(index); +void Writer::beginArg(unsigned index) { + _writeByte(Trace::CALL_ARG); + _writeUInt(index); } -void BeginReturn(void) { - WriteByte(Trace::CALL_RET); +void Writer::beginReturn(void) { + _writeByte(Trace::CALL_RET); } -void BeginArray(size_t length) { - WriteByte(Trace::TYPE_ARRAY); - WriteUInt(length); +void Writer::beginArray(size_t length) { + _writeByte(Trace::TYPE_ARRAY); + _writeUInt(length); } -void BeginStruct(const StructSig *sig) { - WriteByte(Trace::TYPE_STRUCT); - WriteUInt(sig->id); +void Writer::beginStruct(const StructSig *sig) { + _writeByte(Trace::TYPE_STRUCT); + _writeUInt(sig->id); if (!lookup(structs, sig->id)) { - WriteString(sig->name); - WriteUInt(sig->num_members); + _writeString(sig->name); + _writeUInt(sig->num_members); for (unsigned i = 0; i < sig->num_members; ++i) { - WriteString(sig->members[i]); + _writeString(sig->member_names[i]); } structs[sig->id] = true; } } -void LiteralBool(bool value) { - WriteByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE); +void Writer::writeBool(bool value) { + _writeByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE); } -void LiteralSInt(signed long long value) { +void Writer::writeSInt(signed long long value) { if (value < 0) { - WriteByte(Trace::TYPE_SINT); - WriteUInt(-value); + _writeByte(Trace::TYPE_SINT); + _writeUInt(-value); } else { - WriteByte(Trace::TYPE_UINT); - WriteUInt(value); + _writeByte(Trace::TYPE_UINT); + _writeUInt(value); } } -void LiteralUInt(unsigned long long value) { - WriteByte(Trace::TYPE_UINT); - WriteUInt(value); +void Writer::writeUInt(unsigned long long value) { + _writeByte(Trace::TYPE_UINT); + _writeUInt(value); } -void LiteralFloat(float value) { - WriteByte(Trace::TYPE_FLOAT); - WriteFloat(value); +void Writer::writeFloat(float value) { + _writeByte(Trace::TYPE_FLOAT); + _writeFloat(value); } -void LiteralDouble(double value) { - WriteByte(Trace::TYPE_DOUBLE); - WriteDouble(value); +void Writer::writeDouble(double value) { + _writeByte(Trace::TYPE_DOUBLE); + _writeDouble(value); } -void LiteralString(const char *str) { +void Writer::writeString(const char *str) { if (!str) { - LiteralNull(); + Writer::writeNull(); return; } - WriteByte(Trace::TYPE_STRING); - WriteString(str); + _writeByte(Trace::TYPE_STRING); + _writeString(str); } -void LiteralString(const char *str, size_t len) { +void Writer::writeString(const char *str, size_t len) { if (!str) { - LiteralNull(); + Writer::writeNull(); return; } - WriteByte(Trace::TYPE_STRING); - WriteUInt(len); - Write(str, len); + _writeByte(Trace::TYPE_STRING); + _writeUInt(len); + _write(str, len); } -void LiteralWString(const wchar_t *str) { +void Writer::writeWString(const wchar_t *str) { if (!str) { - LiteralNull(); + Writer::writeNull(); return; } - WriteByte(Trace::TYPE_STRING); - WriteString(""); + _writeByte(Trace::TYPE_STRING); + _writeString(""); } -void LiteralBlob(const void *data, size_t size) { +void Writer::writeBlob(const void *data, size_t size) { if (!data) { - LiteralNull(); + Writer::writeNull(); return; } - WriteByte(Trace::TYPE_BLOB); - WriteUInt(size); + _writeByte(Trace::TYPE_BLOB); + _writeUInt(size); if (size) { - Write(data, size); + _write(data, size); } } -void LiteralEnum(const EnumSig *sig) { - WriteByte(Trace::TYPE_ENUM); - WriteUInt(sig->id); +void Writer::writeEnum(const EnumSig *sig) { + _writeByte(Trace::TYPE_ENUM); + _writeUInt(sig->id); if (!lookup(enums, sig->id)) { - WriteString(sig->name); - LiteralSInt(sig->value); + _writeString(sig->name); + Writer::writeSInt(sig->value); enums[sig->id] = true; } } -void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) { - WriteByte(Trace::TYPE_BITMASK); - WriteUInt(bitmask.id); - if (!lookup(bitmasks, bitmask.id)) { - WriteUInt(bitmask.count); - for (unsigned i = 0; i < bitmask.count; ++i) { - if (i != 0 && bitmask.values[i].value == 0) { - OS::DebugMessage("apitrace: bitmask %s is zero but is not first flag\n", bitmask.values[i].name); +void Writer::writeBitmask(const BitmaskSig *sig, unsigned long long value) { + _writeByte(Trace::TYPE_BITMASK); + _writeUInt(sig->id); + if (!lookup(bitmasks, sig->id)) { + _writeUInt(sig->num_flags); + for (unsigned i = 0; i < sig->num_flags; ++i) { + if (i != 0 && sig->flags[i].value == 0) { + OS::DebugMessage("apitrace: warning: sig %s is zero but is not first flag\n", sig->flags[i].name); } - WriteString(bitmask.values[i].name); - WriteUInt(bitmask.values[i].value); + _writeString(sig->flags[i].name); + _writeUInt(sig->flags[i].value); } - bitmasks[bitmask.id] = true; + bitmasks[sig->id] = true; } - WriteUInt(value); + _writeUInt(value); } -void LiteralNull(void) { - WriteByte(Trace::TYPE_NULL); +void Writer::writeNull(void) { + _writeByte(Trace::TYPE_NULL); } -void LiteralOpaque(const void *addr) { +void Writer::writeOpaque(const void *addr) { if (!addr) { - LiteralNull(); + Writer::writeNull(); return; } - WriteByte(Trace::TYPE_OPAQUE); - WriteUInt((size_t)addr); + _writeByte(Trace::TYPE_OPAQUE); + _writeUInt((size_t)addr); } -void Abort(void) { - Close(); - OS::Abort(); -} } /* namespace Trace */ - -#ifdef _WIN32 - -#if 0 -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - switch(fdwReason) { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - return TRUE; - case DLL_THREAD_DETACH: - return TRUE; - case DLL_PROCESS_DETACH: - Trace::Close(); - return TRUE; - } - (void)hinstDLL; - (void)lpvReserved; - return TRUE; -} -#endif - -#else - -static void _uninit(void) __attribute__((destructor)); -static void _uninit(void) { - Trace::Close(); -} - -#endif