From: José Fonseca Date: Sat, 28 May 2011 09:37:12 +0000 (+0100) Subject: Turn trace writer into a class. X-Git-Tag: 2.0_alpha^2~854 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eced747755020ebce502ba33555acb88e382aed8;p=tools%2Fapitrace.git Turn trace writer into a class. --- diff --git a/gltrace.py b/gltrace.py index d4adf92..78cc14c 100644 --- a/gltrace.py +++ b/gltrace.py @@ -334,13 +334,13 @@ class GlTracer(Tracer): # Emit a fake function print ' {' print ' static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name - print ' unsigned __call = Trace::BeginEnter(__sig);' - print ' Trace::BeginArg(0);' + print ' unsigned __call = __writer.beginEnter(__sig);' + print ' __writer.beginArg(0);' dump_instance(glapi.GLenum, enable_name) - print ' Trace::EndArg();' - print ' Trace::EndEnter();' - print ' Trace::BeginLeave(__call);' - print ' Trace::EndLeave();' + print ' __writer.endArg();' + print ' __writer.endEnter();' + print ' __writer.beginLeave(__call);' + print ' __writer.endLeave();' print ' }' print ' return;' @@ -424,19 +424,19 @@ class GlTracer(Tracer): Tracer.dispatch_function(self, function) def emit_memcpy(self, dest, src, length): - print ' unsigned __call = Trace::BeginEnter(__memcpy_sig);' - print ' Trace::BeginArg(0);' - print ' Trace::LiteralOpaque(%s);' % dest - print ' Trace::EndArg();' - print ' Trace::BeginArg(1);' - print ' Trace::LiteralBlob(%s, %s);' % (src, length) - print ' Trace::EndArg();' - print ' Trace::BeginArg(2);' - print ' Trace::LiteralUInt(%s);' % length - print ' Trace::EndArg();' - print ' Trace::EndEnter();' - print ' Trace::BeginLeave(__call);' - print ' Trace::EndLeave();' + print ' unsigned __call = __writer.beginEnter(__memcpy_sig);' + print ' __writer.beginArg(0);' + print ' __writer.writeOpaque(%s);' % dest + print ' __writer.endArg();' + print ' __writer.beginArg(1);' + print ' __writer.writeBlob(%s, %s);' % (src, length) + print ' __writer.endArg();' + print ' __writer.beginArg(2);' + print ' __writer.writeUInt(%s);' % length + print ' __writer.endArg();' + print ' __writer.endEnter();' + print ' __writer.beginLeave(__call);' + print ' __writer.endLeave();' buffer_targets = [ 'ARRAY_BUFFER', @@ -482,15 +482,15 @@ class GlTracer(Tracer): print ' if (!__element_array_buffer) {' if isinstance(arg.type, stdapi.Array): Tracer.dump_arg_instance(self, function, arg) - print ' Trace::BeginArray(%s);' % arg.type.length + print ' __writer.beginArray(%s);' % arg.type.length print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length - print ' Trace::BeginElement();' - print ' Trace::LiteralBlob((const void *)%s, count[i]*__gl_type_size(type));' % (arg.name) - print ' Trace::EndElement();' + print ' __writer.beginElement();' + print ' __writer.writeBlob((const void *)%s, count[i]*__gl_type_size(type));' % (arg.name) + print ' __writer.endElement();' print ' }' - print ' Trace::EndArray();' + print ' __writer.endArray();' else: - print ' Trace::LiteralBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name) + print ' __writer.writeBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name) print ' } else {' Tracer.dump_arg_instance(self, function, arg) print ' }' @@ -547,19 +547,19 @@ class GlTracer(Tracer): # Emit a fake function self.array_trace_intermezzo(api, uppercase_name) - print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,) + print ' unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,) for arg in function.args: assert not arg.output - print ' Trace::BeginArg(%u);' % (arg.index,) + print ' __writer.beginArg(%u);' % (arg.index,) if arg.name != 'pointer': dump_instance(arg.type, arg.name) else: - print ' Trace::LiteralBlob((const void *)%s, __size);' % (arg.name) - print ' Trace::EndArg();' + print ' __writer.writeBlob((const void *)%s, __size);' % (arg.name) + print ' __writer.endArg();' - print ' Trace::EndEnter();' - print ' Trace::BeginLeave(__call);' - print ' Trace::EndLeave();' + print ' __writer.endEnter();' + print ' __writer.beginLeave(__call);' + print ' __writer.endLeave();' print ' }' print ' }' self.array_epilog(api, uppercase_name) @@ -591,19 +591,19 @@ class GlTracer(Tracer): print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names) # Emit a fake function - print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,) + print ' unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,) for arg in function.args: assert not arg.output - print ' Trace::BeginArg(%u);' % (arg.index,) + print ' __writer.beginArg(%u);' % (arg.index,) if arg.name != 'pointer': dump_instance(arg.type, arg.name) else: - print ' Trace::LiteralBlob((const void *)%s, __size);' % (arg.name) - print ' Trace::EndArg();' + print ' __writer.writeBlob((const void *)%s, __size);' % (arg.name) + print ' __writer.endArg();' - print ' Trace::EndEnter();' - print ' Trace::BeginLeave(__call);' - print ' Trace::EndLeave();' + print ' __writer.endEnter();' + print ' __writer.beginLeave(__call);' + print ' __writer.endLeave();' print ' }' print ' }' print ' }' @@ -658,15 +658,15 @@ class GlTracer(Tracer): self.fake_call(function, [texture]) def fake_call(self, function, args): - print ' unsigned __fake_call = Trace::BeginEnter(__%s_sig);' % (function.name,) + print ' unsigned __fake_call = __writer.beginEnter(__%s_sig);' % (function.name,) for arg, instance in zip(function.args, args): assert not arg.output - print ' Trace::BeginArg(%u);' % (arg.index,) + print ' __writer.beginArg(%u);' % (arg.index,) dump_instance(arg.type, instance) - print ' Trace::EndArg();' - print ' Trace::EndEnter();' - print ' Trace::BeginLeave(__fake_call);' - print ' Trace::EndLeave();' + print ' __writer.endArg();' + print ' __writer.endEnter();' + print ' __writer.beginLeave(__fake_call);' + print ' __writer.endLeave();' diff --git a/gui/saverthread.cpp b/gui/saverthread.cpp index fe0f9a6..648de59 100644 --- a/gui/saverthread.cpp +++ b/gui/saverthread.cpp @@ -118,7 +118,7 @@ deleteBitmaskSig(Trace::BitmaskSig *sig) } static void -writeValue(const QVariant &var, unsigned &id) +writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) { int arrayType = QMetaType::type("ApiArray"); int bitmaskType = QMetaType::type("ApiBitmask"); @@ -129,73 +129,73 @@ writeValue(const QVariant &var, unsigned &id) switch(type) { case QVariant::Bool: - Trace::LiteralBool(var.toBool()); + writer.writeBool(var.toBool()); break; case QVariant::ByteArray: { QByteArray ba = var.toByteArray(); - Trace::LiteralBlob((const void*)ba.constData(), ba.size()); + writer.writeBlob((const void*)ba.constData(), ba.size()); } break; case QVariant::Double: - Trace::LiteralDouble(var.toDouble()); + writer.writeDouble(var.toDouble()); break; case QMetaType::Float: - Trace::LiteralFloat(var.toFloat()); + writer.writeFloat(var.toFloat()); break; case QVariant::Int: - Trace::LiteralSInt(var.toInt()); + writer.writeSInt(var.toInt()); break; case QVariant::LongLong: - Trace::LiteralSInt(var.toLongLong()); + writer.writeSInt(var.toLongLong()); break; case QVariant::String: { QString str = var.toString(); - Trace::LiteralString(str.toLocal8Bit().constData(), str.length()); + writer.writeString(str.toLocal8Bit().constData(), str.length()); } break; case QVariant::UInt: - Trace::LiteralUInt(var.toInt()); + writer.writeUInt(var.toInt()); break; case QVariant::ULongLong: - Trace::LiteralUInt(var.toLongLong()); + writer.writeUInt(var.toLongLong()); break; default: if (type == arrayType) { ApiArray array = var.value(); QList vals = array.values(); - Trace::BeginArray(vals.count()); + writer.beginArray(vals.count()); foreach(QVariant el, vals) { - Trace::BeginElement(); - writeValue(el, ++id); - Trace::EndElement(); + writer.beginElement(); + writeValue(writer, el, ++id); + writer.endElement(); } - Trace::EndArray(); + writer.endArray(); } else if (type == bitmaskType) { ApiBitmask bm = var.value(); Trace::BitmaskSig *sig = createBitmaskSig(bm, ++id); - LiteralBitmask(*sig, bm.value()); + writer.writeBitmask(*sig, bm.value()); deleteBitmaskSig(sig); } else if (type == structType) { ApiStruct apiStr = var.value(); QList vals = apiStr.values(); Trace::StructSig *str = createStructSig(apiStr, ++id); - Trace::BeginStruct(str); + writer.beginStruct(str); foreach(QVariant val, vals) { - writeValue(val, ++id); + writeValue(writer, val, ++id); } - Trace::EndStruct(); + writer.endStruct(); deleteStructSig(str); } else if (type == pointerType) { ApiPointer apiPtr = var.value(); - //Trace::BeginArray(1); - //Trace::BeginElement(); - Trace::LiteralOpaque((const void*)apiPtr.value()); - //Trace::EndElement(); - //Trace::EndArray(); + //writer.beginArray(1); + //writer.beginElement(); + writer.writeOpaque((const void*)apiPtr.value()); + //writer.endElement(); + //writer.endArray(); } else if (type == enumType) { ApiEnum apiEnum = var.value(); Trace::EnumSig *sig = createEnumSig(apiEnum, ++id); - Trace::LiteralEnum(sig); + writer.writeEnum(sig); deleteEnumSig(sig); } else { qWarning()<<"Unsupported write variant : " @@ -219,39 +219,39 @@ void SaverThread::saveFile(const QString &fileName, void SaverThread::run() { - qputenv("TRACE_FILE", m_fileName.toLocal8Bit()); unsigned id = 0; - qDebug()<<"saver thread!"; - Trace::Open(); + qDebug() << "Saving : " << m_fileName; + Trace::Writer writer; + writer.open(m_fileName.toLocal8Bit()); for (int i = 0; i < m_calls.count(); ++i) { ApiTraceCall *call = m_calls[i]; Trace::FunctionSig *funcSig = createFunctionSig(call, ++id); - unsigned callNo = Trace::BeginEnter(*funcSig); + unsigned callNo = writer.beginEnter(*funcSig); { //args QVariantList vars = call->arguments(); int index = 0; foreach(QVariant var, vars) { - Trace::BeginArg(index++); - writeValue(var, ++id); - Trace::EndArg(); + writer.beginArg(index++); + writeValue(writer, var, ++id); + writer.endArg(); } } - Trace::EndEnter(); - Trace::BeginLeave(callNo); + writer.endEnter(); + writer.beginLeave(callNo); { QVariant ret = call->returnValue(); if (!ret.isNull()) { - Trace::BeginReturn(); - writeValue(ret, ++id); - Trace::EndReturn(); + writer.beginReturn(); + writeValue(writer, ret, ++id); + writer.endReturn(); } } - Trace::EndLeave(); + writer.endLeave(); deleteFunctionSig(funcSig); } - Trace::Close(); + writer.close(); emit traceSaved(); } diff --git a/trace.py b/trace.py index c83d713..618fbad 100644 --- a/trace.py +++ b/trace.py @@ -60,10 +60,10 @@ class DumpDeclarator(stdapi.OnceVisitor): print ' static const Trace::StructSig sig = {' print ' %u, "%s", %u, members' % (int(struct.id), struct.name, len(struct.members)) print ' };' - print ' Trace::BeginStruct(&sig);' + print ' __writer.beginStruct(&sig);' for type, name in struct.members: dump_instance(type, 'value.%s' % (name,)) - print ' Trace::EndStruct();' + print ' __writer.endStruct();' print '}' print @@ -90,10 +90,10 @@ class DumpDeclarator(stdapi.OnceVisitor): print ' sig = &sig%u;' % i print ' break;' print ' default:' - print ' Trace::LiteralSInt(value);' + print ' __writer.writeSInt(value);' print ' return;' print ' }' - print ' Trace::LiteralEnum(sig);' + print ' __writer.writeEnum(sig);' print '}' print @@ -140,13 +140,13 @@ class DumpImplementer(stdapi.Visitor): '''Dump an instance.''' def visit_literal(self, literal, instance): - print ' Trace::Literal%s(%s);' % (literal.format, instance) + print ' __writer.write%s(%s);' % (literal.format, instance) def visit_string(self, string, instance): if string.length is not None: - print ' Trace::LiteralString((const char *)%s, %s);' % (instance, string.length) + print ' __writer.writeString((const char *)%s, %s);' % (instance, string.length) else: - print ' Trace::LiteralString((const char *)%s);' % instance + print ' __writer.writeString((const char *)%s);' % instance def visit_const(self, const, instance): self.visit(const.type, instance) @@ -157,36 +157,36 @@ class DumpImplementer(stdapi.Visitor): def visit_array(self, array, instance): print ' if (%s) {' % instance index = '__i' + array.type.id - print ' Trace::BeginArray(%s);' % (array.length,) + print ' __writer.beginArray(%s);' % (array.length,) print ' for (int %s = 0; %s < %s; ++%s) {' % (index, index, array.length, index) - print ' Trace::BeginElement();' + print ' __writer.beginElement();' self.visit(array.type, '(%s)[%s]' % (instance, index)) - print ' Trace::EndElement();' + print ' __writer.endElement();' print ' }' - print ' Trace::EndArray();' + print ' __writer.endArray();' print ' }' print ' else' - print ' Trace::LiteralNull();' + print ' __writer.writeNull();' def visit_blob(self, blob, instance): - print ' Trace::LiteralBlob(%s, %s);' % (instance, blob.size) + print ' __writer.writeBlob(%s, %s);' % (instance, blob.size) def visit_enum(self, enum, instance): print ' __traceEnum%s(%s);' % (enum.id, instance) def visit_bitmask(self, bitmask, instance): - print ' Trace::LiteralBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance) + print ' __writer.writeBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance) def visit_pointer(self, pointer, instance): print ' if (%s) {' % instance - print ' Trace::BeginArray(1);' - print ' Trace::BeginElement();' + print ' __writer.beginArray(1);' + print ' __writer.beginElement();' dump_instance(pointer.type, "*" + instance) - print ' Trace::EndElement();' - print ' Trace::EndArray();' + print ' __writer.endElement();' + print ' __writer.endArray();' print ' }' print ' else' - print ' Trace::LiteralNull();' + print ' __writer.writeNull();' def visit_handle(self, handle, instance): self.visit(handle.type, instance) @@ -195,10 +195,10 @@ class DumpImplementer(stdapi.Visitor): self.visit(alias.type, instance) def visit_opaque(self, opaque, instance): - print ' Trace::LiteralOpaque((const void *)%s);' % instance + print ' __writer.writeOpaque((const void *)%s);' % instance def visit_interface(self, interface, instance): - print ' Trace::LiteralOpaque((const void *)&%s);' % instance + print ' __writer.writeOpaque((const void *)&%s);' % instance dump_instance = DumpImplementer().visit @@ -307,7 +307,8 @@ class Tracer: self.footer(api) def header(self, api): - pass + print 'Trace::Writer __writer;' + print def footer(self, api): pass @@ -344,21 +345,21 @@ class Tracer: print def trace_function_impl_body(self, function): - print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,) + print ' unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,) for arg in function.args: if not arg.output: self.unwrap_arg(function, arg) self.dump_arg(function, arg) - print ' Trace::EndEnter();' + print ' __writer.endEnter();' self.dispatch_function(function) - print ' Trace::BeginLeave(__call);' + print ' __writer.beginLeave(__call);' for arg in function.args: if arg.output: self.dump_arg(function, arg) self.wrap_arg(function, arg) if function.type is not stdapi.Void: self.dump_ret(function, "__result") - print ' Trace::EndLeave();' + print ' __writer.endLeave();' def dispatch_function(self, function): if function.type is stdapi.Void: @@ -369,9 +370,9 @@ class Tracer: print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args])) def dump_arg(self, function, arg): - print ' Trace::BeginArg(%u);' % (arg.index,) + print ' __writer.beginArg(%u);' % (arg.index,) self.dump_arg_instance(function, arg) - print ' Trace::EndArg();' + print ' __writer.endArg();' def dump_arg_instance(self, function, arg): dump_instance(arg.type, arg.name) @@ -383,9 +384,9 @@ class Tracer: unwrap_instance(arg.type, arg.name) def dump_ret(self, function, instance): - print ' Trace::BeginReturn();' + print ' __writer.beginReturn();' dump_instance(function.type, instance) - print ' Trace::EndReturn();' + print ' __writer.endReturn();' def wrap_ret(self, function, instance): wrap_instance(function.type, instance) @@ -409,10 +410,10 @@ class Tracer: print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {' print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args])) print ' static const Trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (int(method.id), interface.name + '::' + method.name, len(method.args) + 1) - print ' unsigned __call = Trace::BeginEnter(__sig);' - print ' Trace::BeginArg(0);' - print ' Trace::LiteralOpaque((const void *)m_pInstance);' - print ' Trace::EndArg();' + print ' unsigned __call = __writer.beginEnter(__sig);' + print ' __writer.beginArg(0);' + print ' __writer.writeOpaque((const void *)m_pInstance);' + print ' __writer.endArg();' for arg in method.args: if not arg.output: self.unwrap_arg(method, arg) @@ -422,19 +423,19 @@ class Tracer: else: print ' %s __result;' % method.type result = '__result = ' - print ' Trace::EndEnter();' + print ' __writer.endEnter();' print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args])) - print ' Trace::BeginLeave(__call);' + print ' __writer.beginLeave(__call);' for arg in method.args: if arg.output: self.dump_arg(method, arg) self.wrap_arg(method, arg) if method.type is not stdapi.Void: - print ' Trace::BeginReturn();' + print ' __writer.beginReturn();' dump_instance(method.type, "__result") - print ' Trace::EndReturn();' + print ' __writer.endReturn();' wrap_instance(method.type, '__result') - print ' Trace::EndLeave();' + print ' __writer.endLeave();' if method.name == 'QueryInterface': print ' if (ppvObj && *ppvObj) {' print ' if (*ppvObj == m_pInstance) {' diff --git a/trace_writer.cpp b/trace_writer.cpp index ad6df89..18261f5 100644 --- a/trace_writer.cpp +++ b/trace_writer.cpp @@ -30,8 +30,6 @@ #include #include -#include - #include #include "os.hpp" @@ -42,19 +40,51 @@ namespace Trace { -static gzFile g_gzFile = NULL; -static void _Close(void) { +Writer::Writer() : + g_gzFile(NULL), + call_no(0) +{ + close(); +}; + +Writer::~Writer() { + close(); +}; + +void +Writer::close(void) { if (g_gzFile != NULL) { gzclose(g_gzFile); g_gzFile = NULL; } } -static void _Open(const char *szExtension) { - _Close(); +bool +Writer::open(const char *filename) { + close(); + + g_gzFile = gzopen(filename, "wb"); + if (!g_gzFile) { + return false; + } + + call_no = 0; + functions = std::vector(); + structs = std::vector(); + enums = std::vector(); + bitmasks = std::vector(); + + _writeUInt(TRACE_VERSION); + + return true; +} + +void +Writer::open(void) { static unsigned dwCounter = 0; + const char *szExtension = "trace"; char szFileName[PATH_MAX]; const char *lpFileName; @@ -70,41 +100,42 @@ static void _Open(const char *szExtension) { 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; } } OS::DebugMessage("apitrace: tracing to %s\n", szFileName); - g_gzFile = gzopen(szFileName, "wb"); + open(szFileName); } -static inline void Write(const void *sBuffer, size_t dwBytesToWrite) { +void inline +Writer::_write(const void *sBuffer, size_t dwBytesToWrite) { if (g_gzFile == NULL) return; gzwrite(g_gzFile, 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 +150,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,219 +181,180 @@ 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; - +unsigned Writer::beginEnter(const FunctionSig &function) { + OS::AcquireMutex(); -void Close(void) { - _Close(); - call_no = 0; - functions = std::vector(); - structs = std::vector(); - enums = std::vector(); - bitmasks = std::vector(); -} + if (!g_gzFile) { + open(); + } -unsigned BeginEnter(const FunctionSig &function) { - OS::AcquireMutex(); - Open(); - WriteByte(Trace::EVENT_ENTER); - WriteUInt(function.id); + _writeByte(Trace::EVENT_ENTER); + _writeUInt(function.id); if (!lookup(functions, function.id)) { - WriteString(function.name); - WriteUInt(function.num_args); + _writeString(function.name); + _writeUInt(function.num_args); for (unsigned i = 0; i < function.num_args; ++i) { - WriteString(function.args[i]); + _writeString(function.args[i]); } functions[function.id] = true; } + return call_no++; } -void EndEnter(void) { - WriteByte(Trace::CALL_END); +void Writer::endEnter(void) { + _writeByte(Trace::CALL_END); gzflush(g_gzFile, Z_SYNC_FLUSH); OS::ReleaseMutex(); } -void BeginLeave(unsigned call) { +void Writer::beginLeave(unsigned call) { OS::AcquireMutex(); - WriteByte(Trace::EVENT_LEAVE); - WriteUInt(call); + _writeByte(Trace::EVENT_LEAVE); + _writeUInt(call); } -void EndLeave(void) { - WriteByte(Trace::CALL_END); +void Writer::endLeave(void) { + _writeByte(Trace::CALL_END); gzflush(g_gzFile, Z_SYNC_FLUSH); OS::ReleaseMutex(); } -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->members[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); +void Writer::writeBitmask(const BitmaskSig &bitmask, unsigned long long value) { + _writeByte(Trace::TYPE_BITMASK); + _writeUInt(bitmask.id); if (!lookup(bitmasks, bitmask.id)) { - WriteUInt(bitmask.count); + _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); } - WriteString(bitmask.values[i].name); - WriteUInt(bitmask.values[i].value); + _writeString(bitmask.values[i].name); + _writeUInt(bitmask.values[i].value); } bitmasks[bitmask.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); } } /* 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 diff --git a/trace_writer.hpp b/trace_writer.hpp index f76cd3f..5e7416b 100644 --- a/trace_writer.hpp +++ b/trace_writer.hpp @@ -32,6 +32,8 @@ #include +#include + namespace Trace { typedef unsigned Id; @@ -67,43 +69,68 @@ namespace Trace { const BitmaskVal *values; }; - void Open(void); - void Close(void); - - unsigned BeginEnter(const FunctionSig &function); - void EndEnter(void); - - void BeginLeave(unsigned call); - void EndLeave(void); - - void BeginArg(unsigned index); - inline void EndArg(void) {} - - void BeginReturn(void); - inline void EndReturn(void) {} + class Writer { + protected: + void *g_gzFile; + unsigned call_no; + + std::vector functions; + std::vector structs; + std::vector enums; + std::vector bitmasks; + + public: + Writer(); + ~Writer(); + + void open(void); + bool open(const char *filename); + void close(void); + + unsigned beginEnter(const FunctionSig &function); + void endEnter(void); + + void beginLeave(unsigned call); + void endLeave(void); + + void beginArg(unsigned index); + inline void endArg(void) {} + + void beginReturn(void); + inline void endReturn(void) {} + + void beginArray(size_t length); + inline void endArray(void) {} + + inline void beginElement(void) {} + inline void endElement(void) {} + + void beginStruct(const StructSig *sig); + inline void endStruct(void) {} + + void writeBool(bool value); + void writeSInt(signed long long value); + void writeUInt(unsigned long long value); + void writeFloat(float value); + void writeDouble(double value); + void writeString(const char *str); + void writeString(const char *str, size_t size); + void writeWString(const wchar_t *str); + void writeBlob(const void *data, size_t size); + void writeEnum(const EnumSig *sig); + void writeBitmask(const BitmaskSig &bitmask, unsigned long long value); + void writeNull(void); + void writeOpaque(const void *ptr); + + protected: + void inline _write(const void *sBuffer, size_t dwBytesToWrite); + void inline _writeByte(char c); + void inline _writeUInt(unsigned long long value); + void inline _writeFloat(float value); + void inline _writeDouble(double value); + void inline _writeString(const char *str); - void BeginArray(size_t length); - inline void EndArray(void) {} - - inline void BeginElement(void) {} - inline void EndElement(void) {} - - void BeginStruct(const StructSig *sig); - inline void EndStruct(void) {} - - void LiteralBool(bool value); - void LiteralSInt(signed long long value); - void LiteralUInt(unsigned long long value); - void LiteralFloat(float value); - void LiteralDouble(double value); - void LiteralString(const char *str); - void LiteralString(const char *str, size_t size); - void LiteralWString(const wchar_t *str); - void LiteralBlob(const void *data, size_t size); - void LiteralEnum(const EnumSig *sig); - void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value); - void LiteralNull(void); - void LiteralOpaque(const void *ptr); + }; } #endif /* _TRACE_WRITER_HPP_ */