X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=log.cpp;h=7e219700988acad8e12ba6f0324885aa49a193f1;hb=588bd47c876d60f0c1899e95ad7ce10704e78352;hp=20df332ad9908e6c96c7874bfe40762058b85397;hpb=3bccbb1d72f99497e3f0499dbe5f335d0176709a;p=apitrace diff --git a/log.cpp b/log.cpp index 20df332..7e21970 100644 --- a/log.cpp +++ b/log.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright 2008 Jose Fonseca + * Copyright 2008-2009 VMware, Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -18,136 +18,133 @@ ****************************************************************************/ +#include #include +#include +#include + +#include + +#include #include "log.hpp" +#ifdef WIN32 +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif +#ifndef snprintf +#define snprintf _snprintf +#endif +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif + + namespace Log { -static HANDLE g_hFile = INVALID_HANDLE_VALUE; -static TCHAR g_szFileName[MAX_PATH]; +static gzFile g_gzFile = NULL; +static char g_szFileName[PATH_MAX]; +static CRITICAL_SECTION CriticalSection; static void _Close(void) { - if(g_hFile != INVALID_HANDLE_VALUE) { - CloseHandle(g_hFile); - g_hFile = INVALID_HANDLE_VALUE; + if(g_gzFile != NULL) { + gzclose(g_gzFile); + g_gzFile = NULL; + DeleteCriticalSection(&CriticalSection); } } -static void _Open(const TCHAR *szName, const TCHAR *szExtension) { +static void _Open(const char *szName, const char *szExtension) { _Close(); - DWORD dwCounter = 0; - do { - if(dwCounter) - _sntprintf(g_szFileName, MAX_PATH, TEXT("%s.%u.%s"), szName, dwCounter, szExtension); - else - _sntprintf(g_szFileName, MAX_PATH, TEXT("%s.%s"), szName, szExtension); - - g_hFile = CreateFile(g_szFileName, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, - NULL); - ++dwCounter; - } while(g_hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS); -} + static unsigned dwCounter = 0; -static void _ReOpen(void) { - _Close(); - - g_hFile = CreateFile(g_szFileName, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); -} + char szProcessPath[PATH_MAX]; + char *lpProcessName; + char *lpProcessExt; -static void Write(const char *sBuffer, DWORD dwBytesToWrite) { - if(g_hFile == INVALID_HANDLE_VALUE) - return; - - DWORD dwBytesWritten = 0; - - while (dwBytesWritten < dwBytesToWrite) { - OVERLAPPED overlapped; - memset(&overlapped, 0, sizeof(OVERLAPPED)); + GetModuleFileNameA(NULL, szProcessPath, sizeof(szProcessPath)/sizeof(szProcessPath[0])); - /* Write to end of file */ - overlapped.Offset = 0xffffffff; - overlapped.OffsetHigh = 0xffffffff; + lpProcessName = strrchr(szProcessPath, '\\'); + lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath; + lpProcessExt = strrchr(lpProcessName, '.'); + if(lpProcessExt) + *lpProcessExt = '\0'; + + for(;;) { + FILE *file; - if(WriteFile(g_hFile, - sBuffer + dwBytesWritten, - dwBytesToWrite - dwBytesWritten, - &dwBytesWritten, - &overlapped) == FALSE) { - _Close(); - _Open(TEXT("extra"), TEXT("xml")); - return; - } + if(dwCounter) + snprintf(g_szFileName, PATH_MAX, "%s.%s.%u.%s.gz", lpProcessName, szName, dwCounter, szExtension); + else + snprintf(g_szFileName, PATH_MAX, "%s.%s.%s.gz", lpProcessName, szName, szExtension); + + file = fopen(g_szFileName, "rb"); + if(file == NULL) + break; + + fclose(file); + + ++dwCounter; } -} -static void Write(const char *szText) { - Write(szText, (DWORD)strlen(szText)); + g_gzFile = gzopen(g_szFileName, "wb"); + InitializeCriticalSection(&CriticalSection); } -void Open(const TCHAR *szName) { - _Open(szName, TEXT("xml")); - Write(""); - NewLine(); - Write(""); - NewLine(); - Write(""); - NewLine(); +static inline void _ReOpen(void) { + /* XXX */ } -void ReOpen(void) { - _ReOpen(); +static inline void Write(const char *sBuffer, size_t dwBytesToWrite) { + if(g_gzFile == NULL) + return; + + gzwrite(g_gzFile, sBuffer, dwBytesToWrite); } -void Close(void) { - Write(""); - NewLine(); - _Close(); +static inline void Write(const char *szText) { + Write(szText, strlen(szText)); } -static void Escape(const char *s) { +static inline void +Escape(const char *s) { /* FIXME */ Write(s); } +static inline void +Indent(unsigned level) { + for(unsigned i = 0; i < level; ++i) + Write("\t"); +} -DWORD g_dwIndent = 0; - -void NewLine(void) { +static inline void +NewLine(void) { Write("\r\n"); - for(unsigned i = 0; i < g_dwIndent; ++i) - Write("\t"); } -void Tag(const char *name) { +static inline void +Tag(const char *name) { Write("<"); Write(name); Write("/>"); } -void BeginTag(const char *name) { +static inline void +BeginTag(const char *name) { Write("<"); Write(name); Write(">"); - ++g_dwIndent; } -void BeginTag(const char *name, - const char *attr1, const char *value1) { +static inline void +BeginTag(const char *name, + const char *attr1, const char *value1) { Write("<"); Write(name); Write(" "); @@ -155,12 +152,12 @@ void BeginTag(const char *name, Write("=\""); Escape(value1); Write("\">"); - ++g_dwIndent; } -void BeginTag(const char *name, - const char *attr1, const char *value1, - const char *attr2, const char *value2) { +static inline void +BeginTag(const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2) { Write("<"); Write(name); Write(" "); @@ -172,10 +169,10 @@ void BeginTag(const char *name, Write("=\""); Escape(value2); Write("\">"); - ++g_dwIndent; } -void BeginTag(const char *name, +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) { @@ -194,16 +191,35 @@ void BeginTag(const char *name, Write("=\""); Escape(value3); Write("\">"); - ++g_dwIndent; } -void EndTag(const char *name) { - --g_dwIndent; +static inline void +EndTag(const char *name) { Write(""); } +void Open(const char *name) { + _Open(name, "xml"); + Write(""); + NewLine(); + Write(""); + NewLine(); + BeginTag("trace"); + NewLine(); +} + +void ReOpen(void) { + _ReOpen(); +} + +void Close(void) { + EndTag("trace"); + NewLine(); + _Close(); +} + void Text(const char *text) { Escape(text); } @@ -224,17 +240,43 @@ void TextF(const char *format, ...) { Text(szBuffer); } +static LARGE_INTEGER frequency = {0}; +static LARGE_INTEGER startcounter; + void BeginCall(const char *function) { + EnterCriticalSection(&CriticalSection); + Indent(1); BeginTag("call", "name", function); NewLine(); + + if(!frequency.QuadPart) + QueryPerformanceFrequency(&frequency); + + QueryPerformanceCounter(&startcounter); } void EndCall(void) { + LARGE_INTEGER endcounter; + LONGLONG usecs; + + QueryPerformanceCounter(&endcounter); + usecs = (endcounter.QuadPart - startcounter.QuadPart)*1000000/frequency.QuadPart; + + Indent(2); + BeginTag("duration"); + TextF("%llu", usecs); + EndTag("duration"); + NewLine(); + + Indent(1); EndTag("call"); NewLine(); + gzflush(g_gzFile, Z_SYNC_FLUSH); + LeaveCriticalSection(&CriticalSection); } void BeginArg(const char *type, const char *name) { + Indent(2); BeginTag("arg", "type", type, "name", name); } @@ -244,6 +286,7 @@ void EndArg(void) { } void BeginReturn(const char *type) { + Indent(2); BeginTag("ret", "type", type); } @@ -266,7 +309,7 @@ void EndElement(void) { void BeginReference(const char *type, const void *addr) { char saddr[256]; - _snprintf(saddr, sizeof(saddr), "%p", addr); + snprintf(saddr, sizeof(saddr), "%p", addr); BeginTag("ref", "type", type, "addr", saddr); } @@ -290,7 +333,7 @@ void DumpString(const char *str) { else if(c == '\r') Text("\\r"); else if(c == '\n') - Text("\\n"); + Text(" "); else { unsigned char octal0 = c & 0x7; unsigned char octal1 = (c >> 3) & 0x7; @@ -306,4 +349,36 @@ void DumpString(const char *str) { Log::Text("\""); } +void DumpWString(const wchar_t *str) { + const wchar_t *p = str; + Log::Text("L\""); + wchar_t c; + while((c = *p++) != 0) { + if(c == '\"') + Text("\\\""); + else if(c == '\\') + Text("\\\\"); + else if(c >= 0x20 && c <= 0x7e) + TextChar((char)c); + else if(c == '\t') + Text("\\t"); + else if(c == '\r') + Text("\\r"); + else if(c == '\n') + Text(" "); + else { + unsigned octal0 = c & 0x7; + unsigned octal1 = (c >> 3) & 0x7; + unsigned octal2 = (c >> 3) & 0x7; + if(octal2) + TextF("\\%u%u%u", octal2, octal1, octal0); + else if(octal1) + TextF("\\%u%u", octal1, octal0); + else + TextF("\\%u", octal0); + } + } + Log::Text("\""); +} + } /* namespace Log */