]> git.cworth.org Git - apitrace/blobdiff - log.cpp
First stab at binary trace and retracing.
[apitrace] / log.cpp
diff --git a/log.cpp b/log.cpp
index a7128f802272d3be25c00c96a4e322170274b44d..a78ba5358e627dc1d3b44fa296c68a0f56f77ad6 100644 (file)
--- a/log.cpp
+++ b/log.cpp
@@ -24,6 +24,7 @@
  **************************************************************************/
 
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,6 +34,7 @@
 
 #include "os.hpp"
 #include "log.hpp"
+#include "trace_format.hpp"
 
 
 namespace Log {
@@ -40,397 +42,230 @@ namespace Log {
 
 static gzFile g_gzFile = NULL;
 static void _Close(void) {
-    if(g_gzFile != NULL) {
-        gzclose(g_gzFile);
-        g_gzFile = NULL;
-    }
+   if(g_gzFile != NULL) {
+      gzclose(g_gzFile);
+      g_gzFile = NULL;
+   }
 }
 
 static void _Open(const char *szName, const char *szExtension) {
-    _Close();
-    
-    static unsigned dwCounter = 0;
-
-    char szProcessName[PATH_MAX];
-    char szFileName[PATH_MAX];
-
-    OS::GetProcessName(szProcessName, PATH_MAX);
-
-    for(;;) {
-        FILE *file;
-        
-        if(dwCounter)
-            snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s.gz", szProcessName, szName, dwCounter, szExtension);
-        else
-            snprintf(szFileName, PATH_MAX, "%s.%s.%s.gz", szProcessName, szName, szExtension);
-        
-        file = fopen(szFileName, "rb");
-        if(file == NULL)
-            break;
-        
-        fclose(file);
-        
-        ++dwCounter;
-    }
-
-    fprintf(stderr, "Logging to %s\n", szFileName);
-    g_gzFile = gzopen(szFileName, "wb");
+   _Close();
+   
+   static unsigned dwCounter = 0;
+
+   char szProcessName[PATH_MAX];
+   char szFileName[PATH_MAX];
+
+   OS::GetProcessName(szProcessName, PATH_MAX);
+
+   for(;;) {
+      FILE *file;
+      
+      if(dwCounter)
+         snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s", szProcessName, szName, dwCounter, szExtension);
+      else
+         snprintf(szFileName, PATH_MAX, "%s.%s.%s", szProcessName, szName, szExtension);
+      
+      file = fopen(szFileName, "rb");
+      if(file == NULL)
+         break;
+      
+      fclose(file);
+      
+      ++dwCounter;
+   }
+
+   fprintf(stderr, "Logging to %s\n", szFileName);
+   g_gzFile = gzopen(szFileName, "wb");
 }
 
 static inline void Write(const char *sBuffer, size_t dwBytesToWrite) {
-    if(g_gzFile == NULL)
-        return;
-    
-    gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
-}
-
-static inline void Write(const char *szText) {
-    Write(szText, strlen(szText));
-}
-
-static inline void Write(char c) 
-{
-    Write(&c, 1);
-}
-
-static inline void
-WriteF(const char *format, ...) 
-{
-    char szBuffer[4096];
-    va_list ap;
-    va_start(ap, format);
-    vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
-    va_end(ap);
-    Write(szBuffer);
+   if(g_gzFile == NULL)
+      return;
+   
+   gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
 }
 
 static inline void 
-Escape(wchar_t c) 
-{
-    switch(c) {
-    case '&':
-        Write("&amp;");
-        break;
-    case '<':
-        Write("&lt;");
-        break;
-    case '>':
-        Write("&gt;");
-        break;
-    case '"':
-        Write("&quot;");
-        break;
-    case '\'':
-        Write("&apos;");
-        break;
-    case '\t':
-        Write("&#09;");
-        break;
-    case '\r':
-        Write("&#13;");
-        break;
-    case '\n':
-        Write("&#10;");
-        break;
-    default:
-        if (c >= 0x20 && c <= 0x7e) {
-            Write((char)c);
-        } else {
-            Write('.');
-        }
-    }
+WriteByte(char c) {
+   Write(&c, 1);
 }
 
-static inline void 
-Escape(const char *s)
-{
-    unsigned char c;
-    while((c = *s++) != 0) {
-        Escape(c);
-    }
-}
+void inline 
+WriteUInt(unsigned long long value) {
+   char buf[2 * sizeof value];
+   unsigned len;
 
-static inline void 
-Escape(const wchar_t *s)
-{
-    unsigned char c;
-    while((c = *s++) != 0) {
-        Escape(c);
-    }
-}
+   len = 0;
+   do {
+      assert(len < sizeof buf);
+      buf[len] = 0x80 | (value & 0x7f);
+      value >>= 7;
+      ++len;
+   } while (value);
 
-static inline void
-EscapeF(const char *format, ...)
-{
-    char szBuffer[4096];
-    va_list ap;
-    va_start(ap, format);
-    vsnprintf(szBuffer, sizeof(szBuffer), format, ap);
-    va_end(ap);
-    Escape(szBuffer);
-}
-
-static inline void 
-Indent(unsigned level) {
-    for(unsigned i = 0; i < level; ++i)
-        Write("\t");
-}
-
-static inline void 
-NewLine(void) {
-    Write("\r\n");
-}
+   assert(len);
+   buf[len - 1] &= 0x7f;
 
-static inline void 
-Tag(const char *name) {
-    Write("<");
-    Write(name);
-    Write("/>");
+   Write(buf, len);
 }
 
 static inline void 
-BeginTag(const char *name) {
-    Write("<");
-    Write(name);
-    Write(">");
+WriteFloat(float value) {
+   assert(sizeof value == 4);
+   Write((const char *)&value, sizeof value);
 }
 
 static inline void 
-BeginTag(const char *name, 
-         const char *attr1, const char *value1) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\">");
+WriteDouble(double value) {
+   assert(sizeof value == 8);
+   Write((const char *)&value, sizeof value);
 }
 
 static inline void 
-BeginTag(const char *name, 
-         const char *attr1, const char *value1,
-         const char *attr2, const char *value2) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\" ");
-    Write(attr2);
-    Write("=\"");
-    Escape(value2);
-    Write("\">");
-}
-
-static inline void 
-BeginTag(const char *name, 
-              const char *attr1, const char *value1,
-              const char *attr2, const char *value2,
-              const char *attr3, const char *value3) {
-    Write("<");
-    Write(name);
-    Write(" ");
-    Write(attr1);
-    Write("=\"");
-    Escape(value1);
-    Write("\" ");
-    Write(attr2);
-    Write("=\"");
-    Escape(value2);
-    Write("\" ");
-    Write(attr3);
-    Write("=\"");
-    Escape(value3);
-    Write("\">");
-}
-
-static inline void
-EndTag(const char *name) {
-    Write("</");
-    Write(name);
-    Write(">");
+WriteString(const char *str) {
+   size_t len = strlen(str);
+   WriteUInt(len);
+   Write(str, len);
 }
 
 void Open(const char *name) {
-    _Open(name, "xml");
-    Write("<?xml version='1.0' encoding='UTF-8'?>");
-    NewLine();
-    Write("<?xml-stylesheet type='text/xsl' href='apitrace.xsl'?>");
-    NewLine();
-    BeginTag("trace");
-    NewLine();
+   _Open(name, "trace");
+   WriteUInt(TRACE_VERSION);
 }
 
 void Close(void) {
-    EndTag("trace");
-    NewLine();
-    _Close();
+   _Close();
 }
 
 void BeginCall(const char *function) {
-    OS::AcquireMutex();
-    Indent(1);
-    BeginTag("call", "name", function);
-    NewLine();
+   OS::AcquireMutex();
+   WriteString(function);
 }
 
 void EndCall(void) {
-    Indent(1);
-    EndTag("call");
-    NewLine();
-    gzflush(g_gzFile, Z_SYNC_FLUSH);
-    OS::ReleaseMutex();
+   WriteByte(Trace::CALL_END);
+   gzflush(g_gzFile, Z_SYNC_FLUSH);
+   OS::ReleaseMutex();
 }
 
 void BeginArg(const char *type, const char *name) {
-    Indent(2);
-    BeginTag("arg", "type", type, "name", name);
+   WriteByte(Trace::CALL_ARG);
+   WriteString(name);
 }
 
-void EndArg(void) {
-    EndTag("arg");
-    NewLine();
-}
+void EndArg(void) { }
 
 void BeginReturn(const char *type) {
-    Indent(2);
-    BeginTag("ret", "type", type);
+   WriteByte(Trace::CALL_RET);
 }
 
-void EndReturn(void) {
-    EndTag("ret");
-    NewLine();
-}
+void EndReturn(void) { }
 
-void BeginArray(const char *type, size_t length)
-{
-    BeginTag("array", "type", type);
+void BeginArray(const char *type, size_t length) {
+   WriteByte(Trace::TYPE_ARRAY);
+   WriteUInt(length);
 }
 
-void EndArray(void)
-{
-    EndTag("array");
-}
+void EndArray(void) { }
 
-void BeginElement(const char *type)
-{
-    BeginTag("elem", "type", type);
-}
+void BeginElement(const char *type) { }
 
-void EndElement(void)
-{
-    EndTag("elem");
-}
+void EndElement(void) { }
 
-void BeginStruct(const char *type)
-{
-    BeginTag("struct", "type", type);
+void BeginStruct(const char *type) {
+   WriteByte(Trace::TYPE_STRUCT);
 }
 
-void EndStruct(void)
-{
-    EndTag("struct");
+void EndStruct(void) {
+   WriteString("");
 }
 
-void BeginMember(const char *type, const char *name)
-{
-    BeginTag("member", "type", type, "name", name);
+void BeginMember(const char *type, const char *name) {
+   WriteString(name);
 }
 
-void EndMember(void)
-{
-    EndTag("member");
-}
+void EndMember(void) { }
 
-void BeginBitmask(const char *type)
-{
-    BeginTag("bitmask");
+void BeginBitmask(const char *type) {
+   WriteByte(Trace::TYPE_BITMASK);
 }
 
-void EndBitmask(void)
-{
-    EndTag("bitmask");
+void EndBitmask(void) {
+   WriteByte(Trace::TYPE_VOID);
 }
 
 void BeginPointer(const char *type, const void *addr)
 {
-    char saddr[256];
-    snprintf(saddr, sizeof(saddr), "%p", addr);
-    BeginTag("ref", "type", type, "addr", saddr);
+   WriteByte(Trace::TYPE_POINTER);
+   WriteUInt((size_t)addr);
 }
 
-void EndPointer(void)
-{
-    EndTag("ref");
+void EndPointer(void) { }
+
+void LiteralBool(bool value) {
+   WriteByte(Trace::TYPE_BOOL);
+   WriteByte(value ? 0 : 1);
 }
 
-void LiteralBool(bool value)
-{
-    BeginTag("bool");
-    WriteF("%u", value ? 0 : 1);
-    EndTag("bool");
+void LiteralSInt(signed long long value) {
+   if (value < 0) {
+      WriteByte(Trace::TYPE_SINT);
+      WriteUInt(-value);
+   } else {
+      WriteByte(Trace::TYPE_UINT);
+      WriteUInt(value);
+   }
 }
 
-void LiteralSInt(signed long long value)
-{
-    BeginTag("int");
-    WriteF("%lli", value);
-    EndTag("int");
+void LiteralUInt(unsigned long long value) {
+   WriteByte(Trace::TYPE_UINT);
+   WriteUInt(value);
 }
 
-void LiteralUInt(unsigned long long value)
-{
-    BeginTag("uint");
-    WriteF("%llu", value);
-    EndTag("uint");
+void LiteralFloat(float value) {
+   WriteByte(Trace::TYPE_FLOAT);
+   WriteFloat(value);
 }
 
-void LiteralFloat(double value)
-{
-    BeginTag("float");
-    WriteF("%f", value);
-    EndTag("float");
+void LiteralFloat(double value) {
+   WriteByte(Trace::TYPE_DOUBLE);
+   WriteDouble(value);
 }
 
-void LiteralString(const char *str)
-{
-    if (!str) {
-        LiteralNull();
-        return;
-    }
-    BeginTag("string");
-    Escape(str);
-    EndTag("string");
+void LiteralString(const char *str) {
+   if (!str) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_STRING);
+   WriteString(str);
 }
 
-void LiteralWString(const wchar_t *str)
-{
-    if (!str) {
-        LiteralNull();
-        return;
-    }
-    BeginTag("wstring");
-    Escape(str);
-    EndTag("wstring");
+void LiteralWString(const wchar_t *str) {
+
+   if (!str) {
+      LiteralNull();
+      return;
+   }
+   WriteByte(Trace::TYPE_STRING);
+   WriteString("<wide-string>");
 }
-    
-void LiteralNamedConstant(const char *str)
-{
-    BeginTag("const");
-    Escape(str);
-    EndTag("const");
+   
+void LiteralNamedConstant(const char *name, long long value) {
+   WriteByte(Trace::TYPE_CONST);
+   WriteString(name);
+   LiteralSInt(value);
 }
 
-void LiteralNull(void)
-{
-    Tag("null");
+void LiteralNull(void) {
+   WriteByte(Trace::TYPE_POINTER);
+   WriteUInt(0);
+   WriteByte(Trace::TYPE_OPAQUE);
 }
 
-void LiteralOpaque(void)
-{
-    Tag("opaque");
+void LiteralOpaque(void) {
+   WriteByte(Trace::TYPE_OPAQUE);
 }
 
 } /* namespace Log */