diff --git a/api/boinc_api.C b/api/boinc_api.C index 1703e2eda0..6142c64ef8 100644 --- a/api/boinc_api.C +++ b/api/boinc_api.C @@ -21,10 +21,10 @@ // graphics-related code goes in graphics_api.C, not here #ifdef _WIN32 -#include -#include "win/Stackwalker.h" +#include "stdafx.h" #endif +#ifndef _WIN32 #ifdef HAVE_UNISTD_H #include #endif @@ -44,6 +44,7 @@ #include using namespace std; +#endif #include "parse.h" #include "shmem.h" diff --git a/api/boinc_api.h b/api/boinc_api.h index 55242d0443..eb602a3aff 100755 --- a/api/boinc_api.h +++ b/api/boinc_api.h @@ -20,16 +20,13 @@ #ifndef _BOINC_API_ #define _BOINC_API_ +#ifndef _WIN32 #include #include - -#ifdef _WIN32 -#include #endif #include "app_ipc.h" -using namespace std; // **************************************************************************** // **************************************************************************** diff --git a/api/graphics_api.C b/api/graphics_api.C index 3093df82dd..fde5a355e0 100755 --- a/api/graphics_api.C +++ b/api/graphics_api.C @@ -20,14 +20,15 @@ // The part of the BOINC app lib having to do with graphics. // This code is NOT linked into the core client. +#include "config.h" + #ifdef _WIN32 -#include +#include "stdafx.h" extern DWORD WINAPI win_graphics_event_loop( LPVOID duff ); HANDLE graphics_threadh=NULL; -#else -#include "config.h" #endif +#ifndef _WIN32 #ifdef __APPLE_CC__ #include "mac_app_opengl.h" #endif @@ -38,6 +39,7 @@ HANDLE graphics_threadh=NULL; #ifdef HAVE_PTHREAD #include #endif +#endif #include "parse.h" #include "util.h" diff --git a/api/graphics_api.h b/api/graphics_api.h index 4d5870904e..c209a545eb 100755 --- a/api/graphics_api.h +++ b/api/graphics_api.h @@ -1,18 +1,7 @@ #ifndef BOINC_GRAPHICS_API_H #define BOINC_GRAPHICS_API_H -#ifdef __APPLE_CC__ -#ifndef HAVE_GL_LIB -#define HAVE_GL_LIB 1 -#endif -#ifndef HAVE_OPENGL_GL_H -#define HAVE_OPENGL_GL_H -#endif -#include -#endif - #ifdef _WIN32 -#include #ifndef HAVE_GL_LIB #define HAVE_GL_LIB 1 #endif @@ -27,6 +16,16 @@ #endif #endif +#ifdef __APPLE_CC__ +#ifndef HAVE_GL_LIB +#define HAVE_GL_LIB 1 +#endif +#ifndef HAVE_OPENGL_GL_H +#define HAVE_OPENGL_GL_H +#endif +#include +#endif + #ifdef HAVE_GL_H #include #elif defined(HAVE_GL_GL_H) diff --git a/api/gutil.C b/api/gutil.C index 1478b72399..ccdad53d7f 100755 --- a/api/gutil.C +++ b/api/gutil.C @@ -17,28 +17,19 @@ // Contributor(s): // -#ifndef _WIN32 #include "config.h" + +#ifdef _WIN32 +#include "stdafx.h" #endif +#ifndef _WIN32 #include #include #include #include #include -#ifdef _WIN32 -#include -#include "jpeglib.h" -#include "bmplib.h" -#include "tgalib.h" -#include -#include -#include -#else -#include -#endif - #ifdef HAVE_GL_H #include "gl.h" #elif defined(HAVE_GL_GL_H) @@ -65,6 +56,18 @@ #elif defined(HAVE_GLUT_GLUT_H) #include #endif +#endif + +#ifdef _WIN32 +#include "jpeglib.h" +#include "bmplib.h" +#include "tgalib.h" +#include +#include +#include +#else +#include +#endif #include "gutil.h" #include "filesys.h" @@ -1350,7 +1353,7 @@ void print_text(char* string) { if(string==NULL) return; glPushAttrib(GL_LIST_BIT); glListBase(listBase); - glCallLists(strlen(string), GL_UNSIGNED_BYTE, string); + glCallLists((GLsizei)strlen(string), GL_UNSIGNED_BYTE, string); glPopAttrib(); } diff --git a/api/mfile.C b/api/mfile.C index 9bb15fdf6d..9c5225bad2 100644 --- a/api/mfile.C +++ b/api/mfile.C @@ -17,6 +17,11 @@ // Contributor(s): // +#ifdef _WIN32 +#include "stdafx.h" +#endif + +#ifndef _WIN32 #include #include #include @@ -28,6 +33,7 @@ #endif using namespace std; +#endif #include "filesys.h" #include "error_numbers.h" @@ -49,7 +55,7 @@ int MFILE::printf(const char* format, ...) { va_start(ap, format); k = vsprintf(buf2, format, ap); va_end(ap); - n = strlen(buf2); + n = (int)strlen(buf2); buf = (char*)realloc(buf, len+n); if (!buf) { errno = ERR_MALLOC; @@ -67,7 +73,7 @@ size_t MFILE::write(const void *ptr, size_t size, size_t nitems) { return 0; } memcpy( buf+len, ptr, size*nitems ); - len += size*nitems; + len += (int)size*(int)nitems; return nitems; } @@ -83,7 +89,7 @@ int MFILE::_putchar(char c) { } int MFILE::puts(const char* p) { - int n = strlen(p); + int n = (int)strlen(p); buf = (char*)realloc(buf, len+n); if (!buf) { errno = ERR_MALLOC; diff --git a/api/reduce.C b/api/reduce.C index fff497591b..1bac75cffb 100644 --- a/api/reduce.C +++ b/api/reduce.C @@ -1,18 +1,36 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef _WIN32 +#include "stdafx.h" +#include +#endif + +#ifndef _WIN32 #include #include #include #include -#ifdef _WIN32 -#include -#include -#endif - #ifdef __APPLE_CC__ #include #define max(a,b) (a>b?a:b) #define min(a,b) (a>b?b:a) #endif +#endif #include "gutil.h" #include "reduce.h" diff --git a/api/win/Stackwalker.cpp b/api/win/Stackwalker.cpp index 1e835f207f..ee2aff3727 100644 --- a/api/win/Stackwalker.cpp +++ b/api/win/Stackwalker.cpp @@ -7,178 +7,52 @@ * Stackwalker.cpp * * Remarks: - * Dumps memory leaks (unreleased allocations) for CRT-Allocs and COM-Allocs * Dumps the stack of an thread if an exepction occurs * - * Known bugs: - * - If the allocation-RequestID wrap, then allocations will get lost... - * * Author: * Jochen Kalmbach, Germany + * (c) 2002-2003 (Freeware) + * http://www.codeproject.com/tools/leakfinder.asp + * + * License (The zlib/libpng License, http://www.opensource.org/licenses/zlib-license.php): + * + * Copyright (c) 2003 Jochen Kalmbach + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including + * commercial applications, and to alter it and redistribute it freely, subject to + * the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim + * that you wrote the original software. If you use this software in a product, + * an acknowledgment in the product documentation would be appreciated but is + * not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. * *////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include -#include -#include -#include +#ifdef _WIN32 +#include "stdafx.h" +#endif #include "Stackwalker.h" -// If the following is defined, only the used memories are stored in the hash-table. -// If the memory is freed, it will be removed from the hash-table (to reduce memory) -// Consequences: At DeInitAllocHook, only Leaks will be reported -#define HASH_ENTRY_REMOVE_AT_FREE - - -// 0 = Do not write any output during runtime-alloc-call -// 1 = Write only the alloc action (malloc, realloc, free) -// 2 = Write alloc action and callstack only for malloc/realloc -// 3 = Write alloc action and callstack for all actions -static ULONG g_ulShowStackAtAlloc = 0; - // the form of the output file -static eAllocCheckOutput g_CallstackOutputType = ACOutput_Simple; - - -// Size of Hash-Table -#define ALLOC_HASH_ENTRIES 1024 - +static eAllocCheckOutput g_CallstackOutputType = ACOutput_XML; // Size of Callstack-trace in bytes (0x500 => appr. 5-9 functions, depending on parameter count for each function) #define MAX_ESP_LEN_BUF 0x500 - -// Normally we can ignore allocations from the Runtime-System -#define IGNORE_CRT_ALLOC - // MaxSize: 128 KByte (only for StackwalkFilter) #define LOG_FILE_MAX_SIZE 1024*128 -// If the following is defined, then COM-Leaks will also be tracked -#define WITH_IMALLOC_SPY - -// ############################################################################################# -#ifdef WITH_IMALLOC_SPY -//forwards: -void IMallocHashInsert(void *pData, CONTEXT &Context, size_t nDataSize); -BOOL IMallocHashRemove(void *pData); - -// IMallocSpy-Interface -class CMallocSpy : public IMallocSpy -{ -public: - CMallocSpy(void) { - m_cbRequest = 0; - } - ~CMallocSpy(void) { - } - // IUnknown methods - STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppUnk) { - HRESULT hr = S_OK; - if (IsEqualIID(riid, IID_IUnknown)) { - *ppUnk = (IUnknown *) this; - } - else if (IsEqualIID(riid, IID_IMallocSpy)) { - *ppUnk = (IMalloc *) this; - } - else { - *ppUnk = NULL; - hr = E_NOINTERFACE; - } - AddRef(); - return hr; - } - STDMETHOD_(ULONG, AddRef) (void) { - return InterlockedIncrement(&m_cRef); - } - STDMETHOD_(ULONG, Release) (void) { - LONG cRef; - cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - { - delete this; - } - return cRef; - } - // IMallocSpy methods - STDMETHOD_(ULONG, PreAlloc) (ULONG cbRequest) { - m_cbRequest = cbRequest; - return cbRequest; - } - STDMETHOD_(void *, PostAlloc) (void *pActual) { - HANDLE hThread; - if (DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, 0, false, DUPLICATE_SAME_ACCESS ) != 0) { - // Ok - CONTEXT c; - memset( &c, '\0', sizeof c ); - c.ContextFlags = CONTEXT_FULL; - if ( GetThreadContext( hThread, &c ) != 0) { - // Ok - IMallocHashInsert(pActual, c, m_cbRequest); - } - CloseHandle(hThread); - } - return pActual; - } - STDMETHOD_(void *, PreFree) (void *pRequest, BOOL fSpyed) { - IMallocHashRemove(pRequest); - return pRequest; - } - STDMETHOD_(void, PostFree) (BOOL fSpyed) { - return; - } - STDMETHOD_(ULONG, PreRealloc) (void *pRequest, ULONG cbRequest, - void **ppNewRequest, BOOL fSpyed) { - IMallocHashRemove(pRequest); - m_cbRequest = cbRequest; - return cbRequest; - } - STDMETHOD_(void *, PostRealloc) (void *pActual, BOOL fSpyed) { - HANDLE hThread; - if (DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, 0, false, DUPLICATE_SAME_ACCESS ) != 0) { - // Ok - CONTEXT c; - memset( &c, '\0', sizeof c ); - c.ContextFlags = CONTEXT_FULL; - if ( GetThreadContext( hThread, &c ) != 0) { - // Ok - IMallocHashInsert(pActual, c, m_cbRequest); - } - CloseHandle(hThread); - } - return pActual; - } - STDMETHOD_(void *, PreGetSize) (void *pRequest, BOOL fSpyed) { - return pRequest; - } - STDMETHOD_(ULONG, PostGetSize) (ULONG cbActual, BOOL fSpyed) { - return cbActual; - } - STDMETHOD_(void *, PreDidAlloc) (void *pRequest, BOOL fSpyed) { - return pRequest; - } - STDMETHOD_(BOOL, PostDidAlloc) (void *pRequest, BOOL fSpyed, BOOL fActual) { - return fActual; - } - STDMETHOD_(void, PreHeapMinimize) (void) { - return; - } - STDMETHOD_(void, PostHeapMinimize) (void) { - return; - } -private: - LONG m_cRef; - ULONG m_cbRequest; -}; -#endif - // ############################################################################################# #ifdef _IMAGEHLP_ #error "'imagehlp.h' should only included here, not before this point! Otherwise there are some problems!" @@ -214,6 +88,12 @@ static void AllocHashOut(FILE*); static ULONG AllocHashOutLeaks(FILE*); +// Global data: +static BOOL g_bInitialized = FALSE; +static HINSTANCE g_hImagehlpDll = NULL; + +static DWORD g_dwShowCount = 0; // increase at every ShowStack-Call +static CRITICAL_SECTION g_csFileOpenClose = {0}; // Globale Vars: static TCHAR *g_pszAllocLogName = NULL; @@ -252,1027 +132,6 @@ static void WriteDateTime(FILE *fFile, BOOL asXMLAttrs = FALSE) { } // WriteDateTime -/******************************************************************************* - * Hash-Tabelle - *******************************************************************************/ -// Memory for the EIP-Address (is used by the ShowStack-method) -#define MAX_EIP_LEN_BUF 4 - -#define ALLOC_ENTRY_NOT_FOUND 0xFFFFFFFF - -typedef struct AllocHashEntryType { - long lRequestID; // RequestID from CRT (if 0, then this entry is empty) - size_t nDataSize; // Size of the allocated memory - char cRemovedFlag; // 0 => memory was not yet released - struct AllocHashEntryType *Next; - // Callstack for EIP - DWORD dwEIPOffset; - DWORD dwEIPLen; - char pcEIPAddr[MAX_EIP_LEN_BUF]; - // Callstack for ESP - DWORD dwESPOffset; - DWORD dwESPLen; - char pcESPAddr[MAX_ESP_LEN_BUF]; -} AllocHashEntryType; - -static AllocHashEntryType AllocHashTable[ALLOC_HASH_ENTRIES]; -static ULONG AllocHashEntries = 0; -static ULONG AllocHashCollisions = 0; -static ULONG AllocHashFreed = 0; -static ULONG AllocHashMaxUsed = 0; // maximal number of concurrent entries -static ULONG AllocHashCurrentCount = 0; - -static ULONG AllocHashMaxCollisions = 0; -static ULONG AllocHashCurrentCollisions = 0; - -// ########################################################################################## -#ifdef WITH_IMALLOC_SPY -// eigene Tabelle für die IMallocs: -typedef struct IMallocHashEntryType { - void *pData; // Key-Word - size_t nDataSize; // größe des Datenblocks (optional) - char cRemovedFlag; // 0 => nicht wurde noch nicht freigegeben - struct IMallocHashEntryType *Next; - // Callstack für EIP - DWORD dwEIPOffset; - DWORD dwEIPLen; - char pcEIPAddr[MAX_EIP_LEN_BUF]; - // Callstack für ESP - DWORD dwESPOffset; - DWORD dwESPLen; - char pcESPAddr[MAX_ESP_LEN_BUF]; -} IMallocHashEntryType; - -static IMallocHashEntryType IMallocHashTable[ALLOC_HASH_ENTRIES]; - -static ULONG IMallocHashEntries = 0; -static ULONG IMallocHashCollisions = 0; -static ULONG IMallocHashFreed = 0; -static ULONG IMallocHashMaxUsed = 0; // maximal number of concurrent entries -static ULONG IMallocHashCurrentCount = 0; - -static ULONG IMallocHashMaxCollisions = 0; -static ULONG IMallocHashCurrentCollisions = 0; - - -//static void AllocHashOut(FILE*); -static ULONG IMallocHashOutLeaks(FILE*); - -// AllocHashFunction -// Die eigentliche Hash-Funktion (hier ganz simpel) -static ULONG IMallocHashFunction(void *pData) { - ULONG ulTemp; - DWORD dwPointer = (DWORD) pData; - - // relativ simpler Mechanismus für die Hash-Funktion, - // mir ist nur nix besseres eingefallen... - ulTemp = dwPointer % ALLOC_HASH_ENTRIES; - - _ASSERTE( (ulTemp >= 0) && (ulTemp < ALLOC_HASH_ENTRIES) ); - - return ulTemp; -} // AllocHashFunction - -// IMallocHashInsert -// pData: Key-Word (Pointer to address) -// pContext: Context-Record, for retrieving Callstack (EIP and EBP is only needed) -// nDataSize: How many bytes -void IMallocHashInsert(void *pData, CONTEXT &Context, size_t nDataSize) { - ULONG HashIdx; - IMallocHashEntryType *pHashEntry; - - // ermittle Statistische Werte - IMallocHashEntries++; - IMallocHashCurrentCount++; - if (IMallocHashCurrentCount > IMallocHashMaxUsed) - IMallocHashMaxUsed = IMallocHashCurrentCount; - - // ermittle den Hash-Wert - HashIdx = IMallocHashFunction(pData); - - // Eintrag darf nicht größer als die Hash-Tabelle sein - _ASSERTE(HashIdx < ALLOC_HASH_ENTRIES); - - pHashEntry = &IMallocHashTable[HashIdx]; - if (pHashEntry->pData == 0) { - // es ist noch kein Eintrag da - } - else { - //Statistische Daten: - IMallocHashCollisions++; - IMallocHashCurrentCollisions++; - if (IMallocHashCurrentCollisions > IMallocHashMaxCollisions) - IMallocHashMaxCollisions = IMallocHashCurrentCollisions; - - // Eintrag ist schon belegt, verkette die Einträge - // wenn dies oft vorkommt, sollte man entweder die Tabelle vergrößern oder eine - // andere Hash-Funktion wählen - while(pHashEntry->Next != NULL) { - pHashEntry = pHashEntry->Next; - } - - pHashEntry->Next = (IMallocHashEntryType*) _calloc_dbg(sizeof(IMallocHashEntryType), 1, _CRT_BLOCK, __FILE__, __LINE__); - pHashEntry = pHashEntry->Next; - - } - pHashEntry->pData = pData; // Key-Word - pHashEntry->nDataSize = nDataSize; - pHashEntry->Next = NULL; - // Get EIP and save it in the record - pHashEntry->dwEIPOffset = Context.Eip; - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Eip, &(pHashEntry->pcEIPAddr), MAX_EIP_LEN_BUF, &(pHashEntry->dwEIPLen)) == 0) { - // Could not read memory... remove everything... - memset(pHashEntry->pcEIPAddr, 0, MAX_EIP_LEN_BUF); - pHashEntry->dwEIPLen = 0; - pHashEntry->dwEIPOffset = 0; - } - - // Get ESP and save it in the record - pHashEntry->dwESPOffset = Context.Ebp; - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Ebp, &(pHashEntry->pcESPAddr), MAX_ESP_LEN_BUF, &(pHashEntry->dwESPLen)) == 0) { - // Could not read memory... remove everything... - memset(pHashEntry->pcESPAddr, 0, MAX_ESP_LEN_BUF); - pHashEntry->dwESPLen = 0; - pHashEntry->dwESPOffset = 0; - - // Check if I tried to read too much... - if (GetLastError() == ERROR_PARTIAL_COPY) - { - // ask how many I can read: - MEMORY_BASIC_INFORMATION MemBuffer; - DWORD dwRet = VirtualQuery((LPCVOID) Context.Ebp, &MemBuffer, sizeof(MemBuffer)); - if (dwRet > 0) - { - // calculate the length - DWORD len = ((DWORD) MemBuffer.BaseAddress + MemBuffer.RegionSize) - Context.Ebp; - if ( (len > 0) && (len < MAX_ESP_LEN_BUF) ) - { - // try to read it again (with the shorter length) - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Ebp, &(pHashEntry->pcESPAddr), len, &(pHashEntry->dwESPLen)) == 0) - { - // ok, now everything goes wrong... remove it... - memset(pHashEntry->pcESPAddr, 0, MAX_ESP_LEN_BUF); - pHashEntry->dwESPLen = 0; - pHashEntry->dwESPOffset = 0; - } - else - { - pHashEntry->dwESPOffset = Context.Ebp; - } - } - } // VirtualQuery was successfully - } // ERROR_PARTIAL_COPY - } -} - -// IMallocHashFind -// Wird ALLOC_ENTRY_NOT_FOUND zurückgegeben, so wurde der Key nicht -// gefunden, ansonsten wird ein Zeiger auf den Hash-Eintrag zurückgegeben -// ACHTUNG: In einem preemptiven Tasking-System kann hier nicht -// garantiert werden, ob der Zeiger noch gültig ist, wenn er -// zurückgegeben wird, da er von einem anderen Thread schon -// freigegeben sein könnte. -// Die synchronisation muß eine Ebene höher erfolgen -static IMallocHashEntryType *IMallocHashFind(void *pData) { - ULONG HashIdx; - IMallocHashEntryType *pHashEntry; - - // ermittle den Hash-Wert - HashIdx = IMallocHashFunction(pData); - - // Eintrag darf nicht größer als die Hash-Tabelle sein - _ASSERTE(HashIdx < ALLOC_HASH_ENTRIES); - - pHashEntry = &IMallocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->pData == pData) { - return pHashEntry; - } - pHashEntry = pHashEntry->Next; - } - - // wenn hier angelangt, dann wurde der Eintrag nicht gefunden! - return (IMallocHashEntryType*) ALLOC_ENTRY_NOT_FOUND; -} // AllocHashFind - -// IMallocHashRemove -// Return: FALSE (0) : Key wurde gefunden und entfernt/markiert -// TRUE (!=0): Key wurde nicht gefunden! -BOOL IMallocHashRemove(void *pData) { - ULONG HashIdx; - IMallocHashEntryType *pHashEntry, *pHashEntryLast; - - // ermittle den Hash-Wert - HashIdx = IMallocHashFunction(pData); - - // Eintrag darf nicht größer als die Hash-Tabelle sein - _ASSERTE(HashIdx < ALLOC_HASH_ENTRIES); - - pHashEntryLast = NULL; - pHashEntry = &IMallocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->pData == pData) { -#ifdef HASH_ENTRY_REMOVE_AT_FREE - IMallocHashFreed++; - IMallocHashCurrentCount--; - // gebe den Speicher frei - if (pHashEntryLast == NULL) { - // Es ist ein Eintrag direkt in der Tabelle - if (pHashEntry->Next == NULL) { - // Es ist der letze Eintrag lösche also die Tabelle - memset(&IMallocHashTable[HashIdx], 0, sizeof(IMallocHashTable[HashIdx])); - } - else { - // Es sind noch Einträge verkettet, überschreibe einfach den nicht mehr gebrauchten... - *pHashEntry = *(pHashEntry->Next); - } - return TRUE; - } - else { - // ich bin in einem dynamischen Bereich - // dies war eine kollisions, zähle also wieder zurück: - IMallocHashCurrentCollisions--; - pHashEntryLast->Next = pHashEntry->Next; - _free_dbg(pHashEntry, _CRT_BLOCK); - return TRUE; - } -#else - // erhöhe nur den Removed counter und behalte das Object im Speicher - pHashEntry->cRemovedFlag++; - return TRUE; // erfolgreich -#endif - } - pHashEntryLast = pHashEntry; - pHashEntry = pHashEntry->Next; - } - - // wenn hier angelangt, dann wurde der Eintrag nicht gefunden! - return FALSE; -} - - - -// Callback-Funtion for StackWalk für meine CallStack-Ausgabe aus der Hash-Tabelle -#if API_VERSION_NUMBER >= 9 -static BOOL __stdcall ReadProcMemoryFromIMallocHash(HANDLE pData, DWORD lpBaseAddress, PVOID lpBuffer, DWORD nSize, PDWORD lpNumberOfBytesRead) { -#else -static BOOL __stdcall ReadProcMemoryFromIMallocHash(HANDLE pData, LPCVOID lpBaseAddress, PVOID lpBuffer, DWORD nSize, PDWORD lpNumberOfBytesRead) { -#endif - // Versuche die hRequestID zu finden - IMallocHashEntryType *pHashEntry; - *lpNumberOfBytesRead = 0; - - pHashEntry = IMallocHashFind((PVOID) pData); - if (pHashEntry == (IMallocHashEntryType*) ALLOC_ENTRY_NOT_FOUND) { - // nicht gefunden, somit kann ich den Speicher nicht lesen - *lpNumberOfBytesRead = 0; - return FALSE; - } - if ( ((DWORD) lpBaseAddress >= pHashEntry->dwESPOffset) && ((DWORD) lpBaseAddress <= (pHashEntry->dwESPOffset+pHashEntry->dwESPLen)) ) { - // Speicher liegt im ESP: - // Errechne den Offset - DWORD dwOffset = (DWORD) lpBaseAddress - pHashEntry->dwESPOffset; - DWORD dwSize = __min(nSize, MAX_ESP_LEN_BUF-dwOffset); - memcpy(lpBuffer, &(pHashEntry->pcESPAddr[dwOffset]), dwSize); - *lpNumberOfBytesRead = dwSize; - if (dwSize != nSize) - return FALSE; - } - - if ( ((DWORD) lpBaseAddress >= pHashEntry->dwEIPOffset) && ((DWORD) lpBaseAddress <= (pHashEntry->dwEIPOffset+pHashEntry->dwEIPLen)) ) { - // Speicher liegt im EIP: - // Errechne den Offset - DWORD dwOffset = (DWORD) lpBaseAddress - pHashEntry->dwEIPOffset; - DWORD dwSize = __min(nSize, MAX_ESP_LEN_BUF-dwOffset); - memcpy(lpBuffer, &(pHashEntry->pcEIPAddr[dwOffset]), dwSize); - *lpNumberOfBytesRead = dwSize; - if (dwSize != nSize) - return FALSE; - } - - if (*lpNumberOfBytesRead == 0) // Der Speicher konnte nicht gefunden werden - return FALSE; - - return TRUE; -} -// AllocHashOutLeaks -// Gibt allen Speicher aus, der noch nicht wieder freigegeben wurde -// Returns the number of bytes, that are not freed (leaks) -ULONG IMallocHashOutLeaks(FILE *fFile) { - ULONG ulTemp; - IMallocHashEntryType *pHashEntry; - ULONG ulCount = 0; - ULONG ulLeaksByte = 0; - - // Gehe jeden Eintrag durch und gebe ihn aus - for(ulTemp = 0; ulTemp < ALLOC_HASH_ENTRIES; ulTemp++) { - pHashEntry = &IMallocHashTable[ulTemp]; - if (pHashEntry->pData != 0) { - while(pHashEntry != NULL) { - // gebe die Zeile aus - if ( (pHashEntry->cRemovedFlag <= 0) || (pHashEntry->cRemovedFlag > 1) ) { - ulCount++; - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("\n"), pHashEntry->pData, pHashEntry->nDataSize); - else - _ftprintf(fFile, _T("Pointer (RequestID): %12i, Removed: %i, Size: %12i\n"), pHashEntry->pData, pHashEntry->cRemovedFlag, pHashEntry->nDataSize); - CONTEXT c; - memset( &c, '\0', sizeof c ); - c.Eip = pHashEntry->dwEIPOffset; - c.Ebp = pHashEntry->dwESPOffset; - ShowStackRM( NULL, c, fFile, &ReadProcMemoryFromIMallocHash, (HANDLE) pHashEntry->pData); - // Zähle zusammen wieviel Byte noch nicht freigegeben wurden - if (pHashEntry->nDataSize > 0) - ulLeaksByte += pHashEntry->nDataSize; - else - ulLeaksByte++; // Wenn zwar Speicher allokiert wurde, dieser aber 0 Bytes lang war, so reserviere für diesen zumindest 1 Byte - - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("\n")); // terminate the xml-node - } - pHashEntry = pHashEntry->Next; - } - } - } - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(fFile, _T("\n**** Number of leaks: %i\n"), ulCount); - return ulLeaksByte; -} // AllocHashOutLeaks -#endif - - -static void AllocHashInit(void) { - - memset(AllocHashTable, 0, sizeof(AllocHashTable)); - AllocHashEntries = 0; - AllocHashCollisions = 0; - AllocHashFreed = 0; - AllocHashCurrentCount = 0; - AllocHashMaxUsed = 0; - - AllocHashMaxCollisions = 0; - AllocHashCurrentCollisions = 0; - -#ifdef WITH_IMALLOC_SPY - memset(IMallocHashTable, 0, sizeof(IMallocHashTable)); - IMallocHashEntries = 0; - IMallocHashCollisions = 0; - IMallocHashFreed = 0; - IMallocHashCurrentCount = 0; - IMallocHashMaxUsed = 0; - - IMallocHashMaxCollisions = 0; - IMallocHashCurrentCollisions = 0; -#endif - return; -} // AllocHashInit - - -// AllocHashDeinit -// Returns the number of bytes, that are not freed (leaks) -static ULONG AllocHashDeinit(void) { - ULONG ulRet = 0; - return 0; - bool bAppend = g_CallstackOutputType != ACOutput_XML; - AllocCheckFileOpen(bAppend); // open global log-file - - if (g_CallstackOutputType == ACOutput_XML) - { - _ftprintf(g_fFile, _T("\n")); - } - else - { - _ftprintf(g_fFile, _T("\n##### Memory Report ########################################\n")); - WriteDateTime(g_fFile); - _ftprintf(g_fFile, _T("\n")); - } - -#ifndef HASH_ENTRY_REMOVE_AT_FREE - // output the used memory - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(g_fFile, _T("##### Memory used: #########################################\n")); - AllocHashOut(g_fFile); -#endif - - // output the Memoty leaks - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(g_fFile, _T("\n##### Leaks: ###############################################\n")); - ulRet = AllocHashOutLeaks(g_fFile); - - if (g_CallstackOutputType == ACOutput_Advanced) - { - // output some statistics from the hash-table - _ftprintf(g_fFile, _T("***** Hash-Table statistics:\n")); - _ftprintf(g_fFile, _T(" Table-Size: %i\n"), ALLOC_HASH_ENTRIES); - _ftprintf(g_fFile, _T(" Inserts: %i\n"), AllocHashEntries); - _ftprintf(g_fFile, _T(" Freed: %i\n"), AllocHashFreed); - _ftprintf(g_fFile, _T(" Sum Collisions: %i\n"), AllocHashCollisions); - _ftprintf(g_fFile, _T("\n")); - _ftprintf(g_fFile, _T(" Max used: %i\n"), AllocHashMaxUsed); - _ftprintf(g_fFile, _T(" Max Collisions: %i\n"), AllocHashMaxCollisions); - } - - // Free Hash-Table - ULONG ulTemp; - AllocHashEntryType *pHashEntry, *pHashEntryOld; - - // Now, free my own memory - for(ulTemp = 0; ulTemp < ALLOC_HASH_ENTRIES; ulTemp++) { - pHashEntry = &AllocHashTable[ulTemp]; - while(pHashEntry != NULL) { - pHashEntryOld = pHashEntry; - pHashEntry = pHashEntry->Next; - if (pHashEntryOld != &AllocHashTable[ulTemp]) { - // now free the dynamically allocated memory - free(pHashEntryOld); - } - } // while - } // for - // empty the hash-table - memset(AllocHashTable, 0, sizeof(AllocHashTable)); - -#ifdef WITH_IMALLOC_SPY - // output the Memoty leaks - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(g_fFile, _T("\n##### COM-Leaks: ###############################################\n")); - ulRet = IMallocHashOutLeaks(g_fFile); - - if (g_CallstackOutputType == ACOutput_Advanced) - { - // output some statistics from the hash-table - _ftprintf(g_fFile, _T("***** Hash-Table statistics:\n")); - _ftprintf(g_fFile, _T(" Table-Size: %i\n"), ALLOC_HASH_ENTRIES); - _ftprintf(g_fFile, _T(" Inserts: %i\n"), IMallocHashEntries); - _ftprintf(g_fFile, _T(" Freed: %i\n"), IMallocHashFreed); - _ftprintf(g_fFile, _T(" Sum Collisions: %i\n"), IMallocHashCollisions); - _ftprintf(g_fFile, _T("\n")); - _ftprintf(g_fFile, _T(" Max used: %i\n"), IMallocHashMaxUsed); - _ftprintf(g_fFile, _T(" Max Collisions: %i\n"), IMallocHashMaxCollisions); - } - - // Free Hash-Table - //ULONG ulTemp; - IMallocHashEntryType *pIMHashEntry, *pIMHashEntryOld; - - // Gehe jeden Eintrag durch und gebe ihn frei - for(ulTemp = 0; ulTemp < ALLOC_HASH_ENTRIES; ulTemp++) { - pIMHashEntry = &IMallocHashTable[ulTemp]; - while(pHashEntry != NULL) { - pIMHashEntryOld = pIMHashEntry; - pIMHashEntry = pIMHashEntry->Next; - if (pIMHashEntryOld != &IMallocHashTable[ulTemp]) { - // es ist dynamischer Speicher, gebe ihn also frei: - _free_dbg(pIMHashEntryOld, _CRT_BLOCK); - } - } // while - } // for - // Lösche die gesamte Hash-Tabelle - memset(IMallocHashTable, 0, sizeof(IMallocHashTable)); -#endif - - - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(g_fFile, _T("\n")); - - return ulRet; -} // AllocHashDeinit - -// AllocHashFunction -// The has-function (very simple) -static inline ULONG AllocHashFunction(long lRequestID) { - // I couldn´t find any better and faster - return lRequestID % ALLOC_HASH_ENTRIES; -} // AllocHashFunction - -// AllocHashInsert -// lRequestID: Key-Word (RequestID from AllocHook) -// pContext: Context-Record, for retrieving Callstack (EIP and EBP is only needed) -// nDataSize: How many bytes -static void AllocHashInsert(long lRequestID, CONTEXT &Context, size_t nDataSize) { - ULONG HashIdx; - AllocHashEntryType *pHashEntry; - - // change statistical data - AllocHashEntries++; - AllocHashCurrentCount++; - if (AllocHashCurrentCount > AllocHashMaxUsed) - AllocHashMaxUsed = AllocHashCurrentCount; - - // generate hash-value - HashIdx = AllocHashFunction(lRequestID); - - pHashEntry = &AllocHashTable[HashIdx]; - if (pHashEntry->lRequestID == 0) { - // Entry is empty... - } - else { - // Entry is not empy! make a list of entries for this hash value... - // change statistical data - // if this happens often, you should increase the hah size or change the heash-function; - // to fasten the allocation time - AllocHashCollisions++; - AllocHashCurrentCollisions++; - if (AllocHashCurrentCollisions > AllocHashMaxCollisions) - AllocHashMaxCollisions = AllocHashCurrentCollisions; - - while(pHashEntry->Next != NULL) { - pHashEntry = pHashEntry->Next; - } - - pHashEntry->Next = (AllocHashEntryType*) calloc(sizeof(AllocHashEntryType), 1); - pHashEntry = pHashEntry->Next; - - } - pHashEntry->lRequestID = lRequestID; // Key-Word - pHashEntry->nDataSize = nDataSize; - pHashEntry->Next = NULL; - // Get EIP and save it in the record - pHashEntry->dwEIPOffset = Context.Eip; - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Eip, &(pHashEntry->pcEIPAddr), MAX_EIP_LEN_BUF, &(pHashEntry->dwEIPLen)) == 0) { - // Could not read memory... remove everything... - memset(pHashEntry->pcEIPAddr, 0, MAX_EIP_LEN_BUF); - pHashEntry->dwEIPLen = 0; - pHashEntry->dwEIPOffset = 0; - } - - // Get ESP and save it in the record - pHashEntry->dwESPOffset = Context.Ebp; - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Ebp, &(pHashEntry->pcESPAddr), MAX_ESP_LEN_BUF, &(pHashEntry->dwESPLen)) == 0) { - // Could not read memory... remove everything... - memset(pHashEntry->pcESPAddr, 0, MAX_ESP_LEN_BUF); - pHashEntry->dwESPLen = 0; - pHashEntry->dwESPOffset = 0; - - // Check if I tried to read too much... - if (GetLastError() == ERROR_PARTIAL_COPY) - { - // ask how many I can read: - MEMORY_BASIC_INFORMATION MemBuffer; - DWORD dwRet = VirtualQuery((LPCVOID) Context.Ebp, &MemBuffer, sizeof(MemBuffer)); - if (dwRet > 0) - { - // calculate the length - DWORD len = ((DWORD) MemBuffer.BaseAddress + MemBuffer.RegionSize) - Context.Ebp; - if ( (len > 0) && (len < MAX_ESP_LEN_BUF) ) - { - // try to read it again (with the shorter length) - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) Context.Ebp, &(pHashEntry->pcESPAddr), len, &(pHashEntry->dwESPLen)) == 0) - { - // ok, now everything goes wrong... remove it... - memset(pHashEntry->pcESPAddr, 0, MAX_ESP_LEN_BUF); - pHashEntry->dwESPLen = 0; - pHashEntry->dwESPOffset = 0; - } - else - { - pHashEntry->dwESPOffset = Context.Ebp; - } - } - } // VirtualQuery was successfully - } // ERROR_PARTIAL_COPY - } -} - -// AllocHashFind -// If ALLOC_ENTRY_NOT_FOUND is returned, the Key was not found! -// If the Key was found, a pointer to the entry is returned -static AllocHashEntryType *AllocHashFind(long lRequestID) { - ULONG HashIdx; - AllocHashEntryType *pHashEntry; - - // get the Hash-Value - HashIdx = AllocHashFunction(lRequestID); - - // Just do some simple checks: - _ASSERTE(HashIdx < ALLOC_HASH_ENTRIES); - - pHashEntry = &AllocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->lRequestID == lRequestID) { - return pHashEntry; - } - pHashEntry = pHashEntry->Next; - } - - // entry was not found! - return (AllocHashEntryType*) ALLOC_ENTRY_NOT_FOUND; -} // AllocHashFind - -// AllocHashRemove -// Return: FALSE (0) : Key was found and removed/marked -// TRUE (!=0): Key was not found -static BOOL AllocHashRemove(long lRequestID) { - ULONG HashIdx; - AllocHashEntryType *pHashEntry, *pHashEntryLast; - - // get the Hash-Value - HashIdx = AllocHashFunction(lRequestID); - - // Just do some simple checks: - _ASSERTE(HashIdx < ALLOC_HASH_ENTRIES); - - pHashEntryLast = NULL; - pHashEntry = &AllocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->lRequestID == lRequestID) { -#ifdef HASH_ENTRY_REMOVE_AT_FREE - AllocHashFreed++; - AllocHashCurrentCount--; - // release my memory - if (pHashEntryLast == NULL) { - // It is an entry in the table, so do not release this memory - if (pHashEntry->Next == NULL) { - // It was the last entry, so empty the table entry - memset(&AllocHashTable[HashIdx], 0, sizeof(AllocHashTable[HashIdx])); - } - else { - // There are some more entries, so shorten the list - *pHashEntry = *(pHashEntry->Next); - // TODO: Do I need to free the memory here !? I think I should do this... - } - return TRUE; - } - else { - // now, I am in an dynamic allocated entry - // it was a collision, so decrease the current collision count - AllocHashCurrentCollisions--; - pHashEntryLast->Next = pHashEntry->Next; - free(pHashEntry); - return TRUE; - } -#else - // increase the Remove-Count and let the objet stay in memory - pHashEntry->cRemovedFlag++; - return TRUE; -#endif - } - pHashEntryLast = pHashEntry; - pHashEntry = pHashEntry->Next; - } - - // if we are here, we could not find the RequestID - return FALSE; -} - -// ReadProcMemoryFromHash -// Callback-Funtion for StackWalk for my own CallStack from the Hash-Table-Entries -#if API_VERSION_NUMBER >= 9 -static BOOL __stdcall ReadProcMemoryFromHash(HANDLE hRequestID, DWORD lpBaseAddress, PVOID lpBuffer, DWORD nSize, PDWORD lpNumberOfBytesRead) { -#else -static BOOL __stdcall ReadProcMemoryFromHash(HANDLE hRequestID, LPCVOID lpBaseAddress, PVOID lpBuffer, DWORD nSize, PDWORD lpNumberOfBytesRead) { -#endif - // Try to find the RequestID - AllocHashEntryType *pHashEntry; - *lpNumberOfBytesRead = 0; - - pHashEntry = AllocHashFind((LONG) hRequestID); - if (pHashEntry == (AllocHashEntryType*) ALLOC_ENTRY_NOT_FOUND) { - // Not found, so I cannot return any memory - *lpNumberOfBytesRead = 0; - return FALSE; - } - if ( ((DWORD) lpBaseAddress >= pHashEntry->dwESPOffset) && ((DWORD) lpBaseAddress <= (pHashEntry->dwESPOffset+pHashEntry->dwESPLen)) ) { - // Memory is located in ESP: - // Calculate the offset - DWORD dwOffset = (DWORD) lpBaseAddress - pHashEntry->dwESPOffset; - DWORD dwSize = __min(nSize, MAX_ESP_LEN_BUF-dwOffset); - memcpy(lpBuffer, &(pHashEntry->pcESPAddr[dwOffset]), dwSize); - *lpNumberOfBytesRead = dwSize; - if (dwSize != nSize) - return FALSE; - } - - if ( ((DWORD) lpBaseAddress >= pHashEntry->dwEIPOffset) && ((DWORD) lpBaseAddress <= (pHashEntry->dwEIPOffset+pHashEntry->dwEIPLen)) ) { - // Memory is located in EIP: - // Calculate the offset - DWORD dwOffset = (DWORD) lpBaseAddress - pHashEntry->dwEIPOffset; - DWORD dwSize = __min(nSize, MAX_ESP_LEN_BUF-dwOffset); - memcpy(lpBuffer, &(pHashEntry->pcEIPAddr[dwOffset]), dwSize); - *lpNumberOfBytesRead = dwSize; - if (dwSize != nSize) - return FALSE; - } - - if (*lpNumberOfBytesRead == 0) // Memory could not be found - return FALSE; - - return TRUE; -} - -// AllocHashOutLeaks -// Write all Memory (with callstack) which was not freed yet -// Returns the number of bytes, that are not freed (leaks) -ULONG AllocHashOutLeaks(FILE *fFile) { - ULONG ulTemp; - AllocHashEntryType *pHashEntry; - ULONG ulCount = 0; - ULONG ulLeaksByte = 0; - - // Move throu every entry - for(ulTemp = 0; ulTemp < ALLOC_HASH_ENTRIES; ulTemp++) { - pHashEntry = &AllocHashTable[ulTemp]; - if (pHashEntry->lRequestID != 0) { - while(pHashEntry != NULL) { - if ( (pHashEntry->cRemovedFlag <= 0) || (pHashEntry->cRemovedFlag > 1) ) { - ulCount++; - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("\n"), pHashEntry->lRequestID, pHashEntry->nDataSize); - else - _ftprintf(fFile, _T("RequestID: %12i, Removed: %i, Size: %12i\n"), pHashEntry->lRequestID, pHashEntry->cRemovedFlag, pHashEntry->nDataSize); - CONTEXT c; - memset( &c, '\0', sizeof c ); - c.Eip = pHashEntry->dwEIPOffset; - c.Ebp = pHashEntry->dwESPOffset; - ShowStackRM( NULL, c, fFile, &ReadProcMemoryFromHash, (HANDLE) pHashEntry->lRequestID); - // Count the number of leaky bytes - if (pHashEntry->nDataSize > 0) - ulLeaksByte += pHashEntry->nDataSize; - else - ulLeaksByte++; // If memory was allocated with zero bytes, then just increase the counter 1 - - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("\n")); // terminate the xml-node - } - pHashEntry = pHashEntry->Next; - } - } - } - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(fFile, _T("\n**** Number of leaks: %i\n"), ulCount); - return ulLeaksByte; -} // AllocHashOutLeaks - -// Write all used memory to a file -void AllocHashOut(FILE *fFile) { - ULONG ulTemp; - AllocHashEntryType *pHashEntry; - - for(ulTemp = 0; ulTemp < ALLOC_HASH_ENTRIES; ulTemp++) { - pHashEntry = &AllocHashTable[ulTemp]; - if (pHashEntry->lRequestID != 0) { - while(pHashEntry != NULL) { - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("lRequestID, pHashEntry->nDataSize); - else - _ftprintf(fFile, _T("RequestID: %12i, Removed: %i, Size: %12i\n"), pHashEntry->lRequestID, pHashEntry->cRemovedFlag, pHashEntry->nDataSize); - pHashEntry = pHashEntry->Next; - } - } - } -} // AllocHashOut - -/******************************************************************************* - * Ende der Hash-Tabelle - *******************************************************************************/ - - -// The follwoing is copied from dbgint.h: -// -/* - * For diagnostic purpose, blocks are allocated with extra information and - * stored in a doubly-linked list. This makes all blocks registered with - * how big they are, when they were allocated, and what they are used for. - */ - -#define nNoMansLandSize 4 - -typedef struct _CrtMemBlockHeader -{ - struct _CrtMemBlockHeader * pBlockHeaderNext; - struct _CrtMemBlockHeader * pBlockHeaderPrev; - char * szFileName; - int nLine; -#ifdef _WIN64 - /* These items are reversed on Win64 to eliminate gaps in the struct - * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is - * maintained in the debug heap. - */ - int nBlockUse; - size_t nDataSize; -#else /* _WIN64 */ - size_t nDataSize; - int nBlockUse; -#endif /* _WIN64 */ - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} _CrtMemBlockHeader; -#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1)) -#define pHdr(pbData) (((_CrtMemBlockHeader *)pbData)-1) - -// - - - - -// Global data: -static BOOL g_bInitialized = FALSE; -static HINSTANCE g_hImagehlpDll = NULL; - -static DWORD g_dwShowCount = 0; // increase at every ShowStack-Call -static CRITICAL_SECTION g_csFileOpenClose = {0}; - -// Is used for syncronising call to MyAllocHook (to prevent reentrant calls) -static LONG g_lMallocCalled = 0; - -static _CRT_ALLOC_HOOK pfnOldCrtAllocHook = NULL; - -// Deaktivate AllocHook, by increasing the Syncronisation-Counter -static void DeactivateMallocStackwalker(void) { - InterlockedIncrement(&g_lMallocCalled); -} - - -// MyAllocHook is Single-Threaded, that means the the calls are serialized in the calling function! -// Special case for VC 5 -#if _MSC_VER <= 1100 -static int MyAllocHook(int nAllocType, void *pvData, - size_t nSize, int nBlockUse, long lRequest, - const char * szFileName, int nLine ) { -#else -static int MyAllocHook(int nAllocType, void *pvData, - size_t nSize, int nBlockUse, long lRequest, - const unsigned char * szFileName, int nLine ) { -#endif - static TCHAR *operation[] = { _T(""), _T("ALLOCATIONG"), _T("RE-ALLOCATING"), _T("FREEING") }; - static TCHAR *blockType[] = { _T("Free"), _T("Normal"), _T("CRT"), _T("Ignore"), _T("Client") }; - -#ifdef IGNORE_CRT_ALLOC - if (_BLOCK_TYPE(nBlockUse) == _CRT_BLOCK) // Ignore internal C runtime library allocations - return TRUE; -#endif - extern int _crtDbgFlag; - if ( ((_CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && ( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) ) ) - { - // Someone has disabled that the runtime should log this allocation - // so we do not log this allocation - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - // Prevent from reentrat calls - if (InterlockedIncrement(&g_lMallocCalled) > 1) { // I was already called - InterlockedDecrement(&g_lMallocCalled); - // call the previous alloc hook - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - if (g_ulShowStackAtAlloc > 0) { - AllocCheckFileOpen(); // Open logfile - } - - _ASSERT( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) || (nAllocType == _HOOK_FREE) ); - _ASSERT( ( _BLOCK_TYPE(nBlockUse) >= 0 ) && ( _BLOCK_TYPE(nBlockUse) < 5 ) ); - - if (nAllocType == _HOOK_FREE) { // freeing - // Try to get the header information - if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer - // get the ID - _CrtMemBlockHeader *pHead; - // get a pointer to memory block header - pHead = pHdr(pvData); - nSize = pHead->nDataSize; - lRequest = pHead->lRequest; // This is the ID! - - if (pHead->nBlockUse == _IGNORE_BLOCK) - { - InterlockedDecrement(&g_lMallocCalled); - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - } - } - - if (g_ulShowStackAtAlloc > 0) { - _ftprintf( g_fFile, _T("##### Memory operation: %s a %d-byte '%s' block (# %ld)"), - operation[nAllocType], nSize, blockType[_BLOCK_TYPE(nBlockUse)], lRequest ); - if ( pvData != NULL ) - _ftprintf( g_fFile, _T(" at 0x%X"), pvData ); - _ftprintf(g_fFile, _T("\n")); - } - - if (nAllocType == _HOOK_FREE) { // freeing: - if (lRequest != 0) { // RequestID was found - BOOL bRet; - // Try to find the RequestID in the Hash-Table, mark it that it was freed - bRet = AllocHashRemove(lRequest); - if(g_ulShowStackAtAlloc > 0) { - if (bRet == FALSE) { - // RequestID not found! - _ftprintf(g_fFile, _T("###### RequestID not found in hash table for FREEING (%i)!\n"), lRequest); - } - } // g_ulShowStackAtAlloc > 0 - } - else { - if(g_ulShowStackAtAlloc > 0) { - // No valid RequestID found, display error - _ftprintf(g_fFile, _T("###### No valid RequestID for FREEING! (0x%X)\n"), pvData); - - } - } - } // freeing - - if (nAllocType == _HOOK_REALLOC) { // re-allocating - // Try to get the header information - if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer - BOOL bRet; - LONG lReallocRequest; - // get the ID - _CrtMemBlockHeader *pHead; - // get a pointer to memory block header - pHead = pHdr(pvData); - // Try to find the RequestID in the Hash-Table, mark it that it was freed - lReallocRequest = pHead->lRequest; - bRet = AllocHashRemove(lReallocRequest); - if (g_ulShowStackAtAlloc > 0) { - if (bRet == FALSE) { - // RequestID not found! - _ftprintf(g_fFile, _T("###### RequestID not found in hash table for RE-ALLOCATING (%i)!\n"), lReallocRequest); - } - else { - _ftprintf(g_fFile, _T("##### Implicit freeing because of re-allocation (# old: %ld, new: %ld)\n"), lReallocRequest, lRequest); - } - } // g_ulShowStackAtAlloc > 0 - } // ValidHeapPointer - } // re-allocating - - if ( (g_ulShowStackAtAlloc < 3) && (nAllocType == _HOOK_FREE) ) { - InterlockedDecrement(&g_lMallocCalled); - // call the previous alloc hook - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - // Get the context DIESES of this Thread - HANDLE hThread; - if (DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, 0, false, DUPLICATE_SAME_ACCESS ) == 0) { - // Something was wrong... - _ftprintf(g_fFile, _T("###### Could not call 'DuplicateHandle' successfully\n")); - InterlockedDecrement(&g_lMallocCalled); - // call the previous alloc hook - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - CONTEXT c; - memset( &c, '\0', sizeof c ); - c.ContextFlags = CONTEXT_FULL; - - // init CONTEXT record so we know where to start the stackwalk - if ( GetThreadContext( hThread, &c ) == 0) { - if(g_ulShowStackAtAlloc > 1) { - _ftprintf(g_fFile, _T("###### Could not call 'GetThreadContext' successfully\n")); - } - InterlockedDecrement(&g_lMallocCalled); - // call the previous alloc hook - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - CloseHandle(hThread); - return TRUE; // could not get context - } - - if(g_ulShowStackAtAlloc > 1) { - if(g_ulShowStackAtAlloc > 2) { - // output the callstack - ShowStack( hThread, c, g_fFile); - } - else { - // Output only (re)allocs - if (nAllocType != _HOOK_FREE) { - ShowStack( hThread, c, g_fFile); - } - } - } // g_ulShowStackAtAlloc > 1 - CloseHandle( hThread ); - - // Only isert in the Hash-Table if it is not a "freeing" - if (nAllocType != _HOOK_FREE) { - if(lRequest != 0) // Always a valid RequestID should be provided (see comments in the header) - AllocHashInsert(lRequest, c, nSize); - } - - InterlockedDecrement(&g_lMallocCalled); - // call the previous alloc hook - if (pfnOldCrtAllocHook != NULL) - pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; // allow the memory operation to proceed -} - - - - // ########################################################################################## // ########################################################################################## // ########################################################################################## @@ -1573,21 +432,14 @@ static int InitStackWalk(void) // old: offer all the functions that are in the NT5 lib // 02-12-19: Now we only support dbghelp.dll! // To use it on NT you have to install the redistrubutable for DBGHELP.DLL - - // BOINC Mod: Check in the BOINC Root folder for dbghelp.dll before the search path. - g_hImagehlpDll = LoadLibrary( _T("..\\..\\dbghelp.dll") ); + g_hImagehlpDll = LoadLibrary( _T("dbghelp.dll") ); if ( g_hImagehlpDll == NULL ) { - g_hImagehlpDll = LoadLibrary( _T("dbghelp.dll") ); - if ( g_hImagehlpDll == NULL ) - { - printf( "LoadLibrary( \"dbghelp.dll\" ): GetLastError = %lu\n", gle ); - g_bInitialized = FALSE; - return 1; - } + printf( "LoadLibrary( \"dbghelp.dll\" ): GetLastError = %lu\n", gle ); + g_bInitialized = FALSE; + return 1; } - pSC = (tSC) GetProcAddress( g_hImagehlpDll, "SymCleanup" ); pSFTA = (tSFTA) GetProcAddress( g_hImagehlpDll, "SymFunctionTableAccess" ); pSGLFA = (tSGLFA) GetProcAddress( g_hImagehlpDll, "SymGetLineFromAddr" ); @@ -1616,49 +468,6 @@ static int InitStackWalk(void) return 0; } -// This function if NOT multi-threading capable -// It should only be called from the main-Function! -int InitAllocCheckWN(eAllocCheckOutput eOutput, LPCTSTR pszFileName, ULONG ulShowStackAtAlloc) { - if (g_bInitialized) { - return 2; // already initialized! - } - if (ulShowStackAtAlloc <= 3) - g_ulShowStackAtAlloc = ulShowStackAtAlloc; - else - g_ulShowStackAtAlloc = 0; - - if (pszFileName != NULL) - g_pszAllocLogName = _tcsdup(pszFileName); - else - g_pszAllocLogName = NULL; - - g_CallstackOutputType = eOutput; - -#ifdef _DEBUG - AllocHashInit(); - -#ifdef WITH_IMALLOC_SPY - HRESULT hr; - // erzeuge mein malloc-Spy object - LPMALLOCSPY pMallocSpy = new CMallocSpy(); // wird später durch Release freigegeben - if (pMallocSpy != NULL) - { - // CoInitilize(); // ??? Ist dies notwendig ? - hr = CoRegisterMallocSpy(pMallocSpy); - if FAILED(hr) - { - _tprintf(_T("\nCoRegisterMallocSpay failed with %.8x"), hr); - } - } -#endif - - // save the previous alloc hook - pfnOldCrtAllocHook = _CrtSetAllocHook(MyAllocHook); -#endif - - return InitStackWalk(); -} // InitAllocCheckWN - static TCHAR s_szExceptionLogFileName[_MAX_PATH] = _T("\\exceptions.log"); // default static BOOL s_bUnhandledExeptionFilterSet = FALSE; static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) @@ -1674,97 +483,11 @@ static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) _T(" Please report!"), pExPtrs->ExceptionRecord->ExceptionCode, pExPtrs->ExceptionRecord->ExceptionFlags, - pExPtrs->ExceptionRecord->ExceptionAddress); + (PVOID)pExPtrs->ExceptionRecord->ExceptionAddress); FatalAppExit(-1,lString); return lRet; } -int InitAllocCheck(eAllocCheckOutput eOutput, BOOL bSetUnhandledExeptionFilter, ULONG ulShowStackAtAlloc) // will create the filename by itself -{ - TCHAR szModName[_MAX_PATH]; - if (GetModuleFileName(NULL, szModName, sizeof(szModName)/sizeof(TCHAR)) != 0) - { - /*_tcscpy(s_szExceptionLogFileName, szModName); - if (eOutput == ACOutput_XML) - _tcscat(s_szExceptionLogFileName, _T(".exp.xml")); - else - _tcscat(s_szExceptionLogFileName, _T(".exp.log"));*/ - - if (eOutput == ACOutput_XML) - _tcscat(szModName, _T(".mem.xml-leaks")); - else - _tcscat(szModName, _T(".mem.log")); - } - else - { - if (eOutput == ACOutput_XML) - _tcscpy(szModName, _T("\\mem-leaks.xml-leaks")); // default - else - _tcscpy(szModName, _T("\\mem-leaks.log")); // default - } - - if (bSetUnhandledExeptionFilter != FALSE) - { - // set global exception handler (for handling all unhandled exceptions) - SetUnhandledExceptionFilter(CrashHandlerExceptionFilter); - s_bUnhandledExeptionFilterSet = TRUE; - } - - return InitAllocCheckWN(eOutput, szModName, ulShowStackAtAlloc); -} - - -// This function if NOT multi-threading capable -// It should only be called from the main-Function! -// Returns the number of bytes that are not freed (leaks) -ULONG DeInitAllocCheck(void) { - ULONG ulRet = 0; - if (g_bInitialized) { - -#ifdef _DEBUG - InterlockedIncrement(&g_lMallocCalled); // No deactivate MyAllocHook, because StackWalker will allocate some memory) - ulRet = AllocHashDeinit(); // output the not freed memory - // remove the hook and set the old one - _CrtSetAllocHook(pfnOldCrtAllocHook); - -#ifdef WITH_IMALLOC_SPY - CoRevokeMallocSpy(); -#endif - -#endif - - EnterCriticalSection(&g_csFileOpenClose); // wait until a running stack dump was created - g_bInitialized = FALSE; - - // de-init symbol handler etc. (SymCleanup()) - if (pSC != NULL) - pSC( GetCurrentProcess() ); - FreeLibrary( g_hImagehlpDll ); - - LeaveCriticalSection(&g_csFileOpenClose); - if (g_pszAllocLogName != NULL) { - free(g_pszAllocLogName); - g_pszAllocLogName = NULL; - } - if (g_fFile != NULL) { - fclose(g_fFile); - g_fFile = NULL; - } - - DeleteCriticalSection(&g_csFileOpenClose); - InterlockedDecrement(&g_lMallocCalled); - } - - if (s_bUnhandledExeptionFilterSet != TRUE) - { - SetUnhandledExceptionFilter(NULL); - s_bUnhandledExeptionFilterSet = FALSE; - } - return ulRet; -} // DeInitAllocCheck - - - static TCHAR *GetExpectionCodeText(DWORD dwExceptionCode) { switch(dwExceptionCode) { @@ -1904,7 +627,7 @@ DWORD StackwalkFilter( EXCEPTION_POINTERS *ep, DWORD status, LPCTSTR pszLogFile) { _ftprintf(fFile, _T("ExceptionRecord->ExceptionCode, - ep->ExceptionRecord->ExceptionAddress); + (PVOID)ep->ExceptionRecord->ExceptionAddress); WriteDateTime(fFile, TRUE); _ftprintf(fFile, _T("code_desc=\"%s\" more_desc=\"%s\">\n"), GetExpectionCodeText(ep->ExceptionRecord->ExceptionCode), GetAdditionalExpectionCodeText(ep->ExceptionRecord)); diff --git a/api/win/Stackwalker.h b/api/win/Stackwalker.h index ed919e602d..cfd93d778e 100644 --- a/api/win/Stackwalker.h +++ b/api/win/Stackwalker.h @@ -26,7 +26,7 @@ #endif // Only MS VC++ 5 to 7 -#if (_MSC_VER < 1100) || (_MSC_VER > 1400) +#if (_MSC_VER < 1100) || (_MSC_VER > 1310) #error Only MS VC++ 5/6/7 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! #endif @@ -41,10 +41,6 @@ typedef enum eAllocCheckOutput #ifdef __cplusplus extern "C" { #endif -extern int InitAllocCheckWN(eAllocCheckOutput eOutput, LPCTSTR pszFilename, ULONG ulShowStackAtAlloc = 0); -extern int InitAllocCheck(eAllocCheckOutput eOutput = ACOutput_Simple, BOOL bSetUnhandledExeptionFilter = TRUE, ULONG ulShowStackAtAlloc = 0); // will create the filename by itself - -extern ULONG DeInitAllocCheck(); extern DWORD StackwalkFilter( EXCEPTION_POINTERS *ep, DWORD status, LPCTSTR pszLogFile); diff --git a/api/windows_opengl.C b/api/windows_opengl.C index ee9043aecc..d390b886b4 100755 --- a/api/windows_opengl.C +++ b/api/windows_opengl.C @@ -14,13 +14,7 @@ * Adapted to BOINC by Eric Heien */ -//remove if there are windows problems -#define WIN32_LEAN_AND_MEAN // This trims down the windows libraries. -#define WIN32_EXTRA_LEAN // Trims even farther. - -#include -#include -#include +#include "stdafx.h" #include "boinc_api.h" #include "graphics_api.h" diff --git a/checkin_notes b/checkin_notes index 3295886102..987463ef08 100755 --- a/checkin_notes +++ b/checkin_notes @@ -10319,7 +10319,7 @@ Rom Mar 4 2004 boinc.dll (Before Changes) 136KB 44KB boinc_gui.exe (After Changes) 1.716MB 428KB - boinc_cli.exe (After Changes) 1.508MB 272KB + boinc_cli.exe (After Changes) 1.508MB 412KB boinc.scr (After Changes) 188KB 116KB boinc.dll (After Changes) 140KB 58KB @@ -10356,8 +10356,18 @@ Rom Mar 4 2004 util.h Rom Mar 5 2004 - - Fix profile path problem that I didn't check-in after fixing it in the alpha project - the first time. + - Include file overhaul for the Windows platform ( Part 2 ) - html/user/ - profile_menu.php + Compiled Source Sizes: Debug Release + boinc_gui.exe (Before Changes) 1.732MB 328KB + boinc_cli.exe (Before Changes) 2.080MB Unknown + boinc.scr (Before Changes) 244KB 88KB + boinc.dll (Before Changes) 136KB 44KB + + boinc_gui.exe (After Changes) 1.716MB 428KB + boinc_cli.exe (After Changes) 624KB 412KB + boinc.scr (After Changes) 188KB 116KB + boinc.dll (After Changes) 140KB 58KB + + I pretty much touched all the source and header files. This checkin should not have any + effect on any platform other than Windows. diff --git a/client/stdafx.h b/client/stdafx.h index 04b4f85c01..944517cd83 100644 --- a/client/stdafx.h +++ b/client/stdafx.h @@ -60,6 +60,7 @@ #include #include #include +#include #include "Stackwalker.h" diff --git a/client/win/Stackwalker.cpp b/client/win/Stackwalker.cpp deleted file mode 100755 index 02ee442939..0000000000 --- a/client/win/Stackwalker.cpp +++ /dev/null @@ -1,1040 +0,0 @@ -/*//////////////////////////////////////////////////////////////////////////// - * Project: - * Exception_Trace - * - * /////////////////////////////////////////////////////////////////////////// - * File: - * Stackwalker.cpp - * - * Remarks: - * Dumps the stack of an thread if an exepction occurs - * - * Author: - * Jochen Kalmbach, Germany - * - *////////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#include "stdafx.h" -#endif - -#include "Stackwalker.h" - -// the form of the output file -static eAllocCheckOutput g_CallstackOutputType = ACOutput_Simple; - -// Size of Callstack-trace in bytes (0x500 => appr. 5-9 functions, depending on parameter count for each function) -#define MAX_ESP_LEN_BUF 0x500 - -// MaxSize: 128 KByte (only for StackwalkFilter) -#define LOG_FILE_MAX_SIZE 1024*128 - -// ############################################################################################# -#ifdef _IMAGEHLP_ -#error "'imagehlp.h' should only included here, not before this point! Otherwise there are some problems!" -#endif -#pragma pack( push, before_imagehlp, 8 ) -#include -#pragma pack( pop, before_imagehlp ) -#if API_VERSION_NUMBER < 7 // ImageHelp-Version is older.... so define it by mayself -// The following definition is only available with VC++ 6.0 or higher, so include it here -extern "C" { -// -// source file line data structure -// -typedef struct _IMAGEHLP_LINE -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) - DWORD Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD Address; // first instruction of line -} IMAGEHLP_LINE, *PIMAGEHLP_LINE; -#define SYMOPT_LOAD_LINES 0x00000010 -} // extern "C" -#endif - - - -// Forward definitions of functions: -static void ShowStackRM( HANDLE hThread, CONTEXT& c, FILE *fLogFile, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryFunction, HANDLE hProcess); -static void ShowStack( HANDLE hThread, CONTEXT& c, FILE *fLogFile); - -static void AllocHashOut(FILE*); -static ULONG AllocHashOutLeaks(FILE*); - - -// Global data: -static BOOL g_bInitialized = FALSE; -static HINSTANCE g_hImagehlpDll = NULL; - -static DWORD g_dwShowCount = 0; // increase at every ShowStack-Call -static CRITICAL_SECTION g_csFileOpenClose = {0}; - -// Globale Vars: -static TCHAR *g_pszAllocLogName = NULL; -static FILE *g_fFile = NULL; - -// AllocCheckFileOpen -// Checks if the log-file is already opened -// if not, try to open file (append or create if not exists) -// if open failed, redirect output to stderr -static void AllocCheckFileOpen(bool bAppend = true) { - // is the File already open? If not open it... - if (g_fFile == NULL) - if (g_pszAllocLogName != NULL) - { - if (bAppend == false) - g_fFile = _tfopen(g_pszAllocLogName, _T("w")); - else - g_fFile = _tfopen(g_pszAllocLogName, _T("a")); - } - if (g_fFile == NULL) - g_fFile = stderr; -} - -// Write Date/Time to specified file (will also work after 2038) -static void WriteDateTime(FILE *fFile, BOOL asXMLAttrs = FALSE) { - TCHAR pszTemp[11], pszTemp2[11]; - - if (fFile != NULL) { - _tstrdate( pszTemp ); - _tstrtime( pszTemp2 ); - if (asXMLAttrs == FALSE) - _ftprintf(fFile, _T("%s %s"), pszTemp, pszTemp2 ); // also ok after year 2038 (asctime is NOT ok) - else - _ftprintf(fFile, _T("date=\"%s\" time=\"%s\" "), pszTemp, pszTemp2 ); // also ok after year 2038 (asctime is NOT ok) - } -} // WriteDateTime - - -// ########################################################################################## -// ########################################################################################## -// ########################################################################################## -// ########################################################################################## - -#define gle (GetLastError()) -#define lenof(a) (sizeof(a) / sizeof((a)[0])) -#define MAXNAMELEN 1024 // max name length for found symbols -#define IMGSYMLEN ( sizeof IMAGEHLP_SYMBOL ) -#define TTBUFLEN 8096 // for a temp buffer (2^13) - - - -// SymCleanup() -typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); -tSC pSC = NULL; - -// SymFunctionTableAccess() -typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD AddrBase ); -tSFTA pSFTA = NULL; - -// SymGetLineFromAddr() -typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD dwAddr, - OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE Line ); -tSGLFA pSGLFA = NULL; - -// SymGetModuleBase() -typedef DWORD (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD dwAddr ); -tSGMB pSGMB = NULL; - -// SymGetModuleInfo() -typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD dwAddr, OUT PIMAGEHLP_MODULE ModuleInfo ); -tSGMI pSGMI = NULL; - -// SymGetOptions() -typedef DWORD (__stdcall *tSGO)( VOID ); -tSGO pSGO = NULL; - -// SymGetSymFromAddr() -typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD dwAddr, - OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_SYMBOL Symbol ); -tSGSFA pSGSFA = NULL; - -// SymInitialize() -typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); -tSI pSI = NULL; - -// SymLoadModule() -typedef DWORD (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, - IN PSTR ImageName, IN PSTR ModuleName, IN DWORD BaseOfDll, IN DWORD SizeOfDll ); -tSLM pSLM = NULL; - -// SymSetOptions() -typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); -tSSO pSSO = NULL; - -// StackWalk() -typedef BOOL (__stdcall *tSW)( DWORD MachineType, HANDLE hProcess, - HANDLE hThread, LPSTACKFRAME StackFrame, PVOID ContextRecord, - PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, - PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, - PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, - PTRANSLATE_ADDRESS_ROUTINE TranslateAddress ); -tSW pSW = NULL; - -// UnDecorateSymbolName() -typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, - DWORD UndecoratedLength, DWORD Flags ); -tUDSN pUDSN = NULL; - - - -struct ModuleEntry -{ - std::string imageName; - std::string moduleName; - DWORD baseAddress; - DWORD size; -}; -typedef std::vector< ModuleEntry > ModuleList; -typedef ModuleList::iterator ModuleListIter; - -// **************************************** ToolHelp32 ************************ -#define MAX_MODULE_NAME32 255 -#define TH32CS_SNAPMODULE 0x00000008 -#pragma pack( push, 8 ) -typedef struct tagMODULEENTRY32 -{ - DWORD dwSize; - DWORD th32ModuleID; // This module - DWORD th32ProcessID; // owning process - DWORD GlblcntUsage; // Global usage count on the module - DWORD ProccntUsage; // Module usage count in th32ProcessID's context - BYTE * modBaseAddr; // Base address of module in th32ProcessID's context - DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr - HMODULE hModule; // The hModule of this module in th32ProcessID's context - char szModule[MAX_MODULE_NAME32 + 1]; - char szExePath[MAX_PATH]; -} MODULEENTRY32; -typedef MODULEENTRY32 * PMODULEENTRY32; -typedef MODULEENTRY32 * LPMODULEENTRY32; -#pragma pack( pop ) - - - -static bool GetModuleListTH32(ModuleList& modules, DWORD pid, FILE *fLogFile) -{ - // CreateToolhelp32Snapshot() - typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); - // Module32First() - typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - // Module32Next() - typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - - // try both dlls... - const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; - HINSTANCE hToolhelp; - tCT32S pCT32S; - tM32F pM32F; - tM32N pM32N; - - HANDLE hSnap; - MODULEENTRY32 me; - me.dwSize = sizeof(me); - bool keepGoing; - ModuleEntry e; - int i; - - for (i = 0; i TTBUFLEN ) - { - _ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); - goto cleanup; - } - - for ( i = 0; i < cbNeeded / sizeof hMods[0]; i++ ) - { - // base address, size - pGMI(hProcess, hMods[i], &mi, sizeof mi ); - e.baseAddress = (DWORD) mi.lpBaseOfDll; - e.size = mi.SizeOfImage; - // image file name - tt[0] = 0; - pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); - e.imageName = tt; - // module name - tt[0] = 0; - pGMBN(hProcess, hMods[i], tt, TTBUFLEN ); - e.moduleName = tt; - - modules.push_back(e); - } - -cleanup: - if (hPsapi) - FreeLibrary(hPsapi); - free(tt); - free(hMods); - - return modules.size() != 0; -} // GetModuleListPSAPI - - -static bool GetModuleList(ModuleList& modules, DWORD pid, HANDLE hProcess, FILE *fLogFile) -{ - // first try toolhelp32 - if (GetModuleListTH32(modules, pid, fLogFile) ) - return true; - // then try psapi - return GetModuleListPSAPI(modules, pid, hProcess, fLogFile); -} // GetModuleList - - -static void EnumAndLoadModuleSymbols( HANDLE hProcess, DWORD pid, FILE *fLogFile ) -{ - static ModuleList modules; - static ModuleListIter it; - char *img, *mod; - - // fill in module list - GetModuleList(modules, pid, hProcess, fLogFile); - - for ( it = modules.begin(); it != modules.end(); ++ it ) - { - // SymLoadModule() wants writeable strings - img = strdup(it->imageName.c_str()); - mod = strdup(it->moduleName.c_str()); - - pSLM( hProcess, 0, img, mod, it->baseAddress, it->size ); - - free(img); - free(mod); - std::string s; - } -} // EnumAndLoadModuleSymbols - -static int InitStackWalk(void) -{ - if (g_bInitialized != FALSE) - return 0; // already initialized - - // old: we load imagehlp.dll dynamically because the NT4-version does not - // old: offer all the functions that are in the NT5 lib - // 02-12-19: Now we only support dbghelp.dll! - // To use it on NT you have to install the redistrubutable for DBGHELP.DLL - g_hImagehlpDll = LoadLibrary( _T("dbghelp.dll") ); - if ( g_hImagehlpDll == NULL ) - { - printf( "LoadLibrary( \"dbghelp.dll\" ): GetLastError = %lu\n", gle ); - g_bInitialized = FALSE; - return 1; - } - - pSC = (tSC) GetProcAddress( g_hImagehlpDll, "SymCleanup" ); - pSFTA = (tSFTA) GetProcAddress( g_hImagehlpDll, "SymFunctionTableAccess" ); - pSGLFA = (tSGLFA) GetProcAddress( g_hImagehlpDll, "SymGetLineFromAddr" ); - pSGMB = (tSGMB) GetProcAddress( g_hImagehlpDll, "SymGetModuleBase" ); - pSGMI = (tSGMI) GetProcAddress( g_hImagehlpDll, "SymGetModuleInfo" ); - pSGO = (tSGO) GetProcAddress( g_hImagehlpDll, "SymGetOptions" ); - pSGSFA = (tSGSFA) GetProcAddress( g_hImagehlpDll, "SymGetSymFromAddr" ); - pSI = (tSI) GetProcAddress( g_hImagehlpDll, "SymInitialize" ); - pSSO = (tSSO) GetProcAddress( g_hImagehlpDll, "SymSetOptions" ); - pSW = (tSW) GetProcAddress( g_hImagehlpDll, "StackWalk" ); - pUDSN = (tUDSN) GetProcAddress( g_hImagehlpDll, "UnDecorateSymbolName" ); - pSLM = (tSLM) GetProcAddress( g_hImagehlpDll, "SymLoadModule" ); - - if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || - pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || - pSW == NULL || pUDSN == NULL || pSLM == NULL ) - { - printf( "GetProcAddress(): some required function not found.\n" ); - FreeLibrary( g_hImagehlpDll ); - g_bInitialized = FALSE; - return 1; - } - - g_bInitialized = TRUE; - InitializeCriticalSection(&g_csFileOpenClose); - return 0; -} - -static TCHAR s_szExceptionLogFileName[_MAX_PATH] = _T("\\exceptions.log"); // default -static BOOL s_bUnhandledExeptionFilterSet = FALSE; -static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) -{ - LONG lRet; - lRet = StackwalkFilter(pExPtrs, /*EXCEPTION_CONTINUE_SEARCH*/EXCEPTION_EXECUTE_HANDLER, NULL); - TCHAR lString[500]; - _stprintf(lString, - _T("*** Unhandled Exception!\n") - _T(" ExpCode: 0x%8.8X\n") - _T(" ExpFlags: %d\n") - _T(" ExpAddress: 0x%8.8X\n") - _T(" Please report!"), - pExPtrs->ExceptionRecord->ExceptionCode, - pExPtrs->ExceptionRecord->ExceptionFlags, - pExPtrs->ExceptionRecord->ExceptionAddress); - FatalAppExit(-1,lString); - return lRet; -} - - -static TCHAR *GetExpectionCodeText(DWORD dwExceptionCode) { - switch(dwExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: return _T("ACCESS VIOLATION"); - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return _T("ARRAY BOUNDS EXCEEDED"); - case EXCEPTION_BREAKPOINT: return _T("BREAKPOINT"); - case EXCEPTION_DATATYPE_MISALIGNMENT: return _T("DATATYPE MISALIGNMENT"); - case EXCEPTION_FLT_DENORMAL_OPERAND: return _T("FLT DENORMAL OPERAND"); - case EXCEPTION_FLT_DIVIDE_BY_ZERO: return _T("FLT DIVIDE BY ZERO"); - case EXCEPTION_FLT_INEXACT_RESULT: return _T("FLT INEXACT RESULT"); - case EXCEPTION_FLT_INVALID_OPERATION: return _T("FLT INVALID OPERATION"); - case EXCEPTION_FLT_OVERFLOW: return _T("FLT OVERFLOW"); - case EXCEPTION_FLT_STACK_CHECK: return _T("FLT STACK CHECK"); - case EXCEPTION_FLT_UNDERFLOW: return _T("FLT UNDERFLOW"); - case EXCEPTION_ILLEGAL_INSTRUCTION: return _T("ILLEGAL INSTRUCTION"); - case EXCEPTION_IN_PAGE_ERROR: return _T("IN PAGE ERROR"); - case EXCEPTION_INT_DIVIDE_BY_ZERO: return _T("INT DIVIDE BY ZERO"); - case EXCEPTION_INT_OVERFLOW: return _T("INT OVERFLOW"); - case EXCEPTION_INVALID_DISPOSITION: return _T("INVALID DISPOSITION"); - case EXCEPTION_NONCONTINUABLE_EXCEPTION: return _T("NONCONTINUABLE EXCEPTION"); - case EXCEPTION_PRIV_INSTRUCTION: return _T("PRIV INSTRUCTION"); - case EXCEPTION_SINGLE_STEP: return _T("SINGLE STEP"); - case EXCEPTION_STACK_OVERFLOW: return _T("STACK OVERFLOW"); - case DBG_CONTROL_C : return _T("DBG CONTROL C "); - default: - return _T(""); - } -} // GetExpectionCodeText - -// Function is not multi-threading safe, because of static char! -static TCHAR *GetAdditionalExpectionCodeText(PEXCEPTION_RECORD pExceptionRecord) { - static TCHAR szTemp[100]; - - switch(pExceptionRecord->ExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: - if (pExceptionRecord->NumberParameters == 2) { - switch(pExceptionRecord->ExceptionInformation[0]) { - case 0: // read attempt - _stprintf(szTemp, _T(" read attempt to address 0x%8.8X "), pExceptionRecord->ExceptionInformation[1]); - return szTemp; - case 1: // write attempt - _stprintf(szTemp, _T(" write attempt to address 0x%8.8X "), pExceptionRecord->ExceptionInformation[1]); - return szTemp; - default: - return _T(""); - } - } // if (pExceptionRecord->NumberParameters == 2) - return _T(""); - default: - return _T(""); - } // switch(pExceptionRecord->ExceptionCode) -} // GetAdditionalExpectionCodeText - -std::string SimpleXMLEncode(PCSTR szText) -{ - std::string szRet; - - for (size_t i=0; i': - szRet.append(">"); - break; - case '"': - szRet.append("""); - break; - case '\'': - szRet.append("'"); - break; - default: - szRet += szText[i]; - } - } - return szRet; -} - - -// ################################################################################# -// ################################################################################# -// Here the Stackwalk-Part begins. -// Some of the code is from an example from a book -// But I couldn´t find the reference anymore... sorry... -// If someone knowns, please let me know... -// ################################################################################# -// ################################################################################# - - -// if you use C++ exception handling: install a translator function -// with set_se_translator(). In the context of that function (but *not* -// afterwards), you can either do your stack dump, or save the CONTEXT -// record as a local copy. Note that you must do the stack sump at the -// earliest opportunity, to avoid the interesting stackframes being gone -// by the time you do the dump. - -// status: -// - EXCEPTION_CONTINUE_SEARCH: exception wird weitergereicht -// - EXCEPTION_CONTINUE_EXECUTION: -// - EXCEPTION_EXECUTE_HANDLER: -DWORD StackwalkFilter( EXCEPTION_POINTERS *ep, DWORD status, LPCTSTR pszLogFile) -{ - HANDLE hThread; - FILE *fFile = stderr; // default to stderr - - if (pszLogFile != NULL) { // a filename is provided - // Open the logfile - fFile = _tfopen(pszLogFile, _T("a")); - if (fFile != NULL) { // Is the file too big? - long size; - fseek(fFile, 0, SEEK_END); - size = ftell(fFile); // Get the size of the file - if (size >= LOG_FILE_MAX_SIZE) { - TCHAR *pszTemp = (TCHAR*) malloc(MAX_PATH); - // It is too big... - fclose(fFile); - _tcscpy(pszTemp, pszLogFile); - _tcscat(pszTemp, _T(".old")); - _tremove(pszTemp); // Remove an old file, if exists - _trename(pszLogFile, pszTemp); // rename the actual file - fFile = _tfopen(pszLogFile, _T("w")); // create a new file - free(pszTemp); - } - } - } // if (pszLogFile != NULL) - if (fFile == NULL) { - fFile = stderr; - } - - // Write infos about the exception - if (g_CallstackOutputType == ACOutput_XML) - { - _ftprintf(fFile, _T("ExceptionRecord->ExceptionCode, - ep->ExceptionRecord->ExceptionAddress); - WriteDateTime(fFile, TRUE); - _ftprintf(fFile, _T("code_desc=\"%s\" more_desc=\"%s\">\n"), GetExpectionCodeText(ep->ExceptionRecord->ExceptionCode), - GetAdditionalExpectionCodeText(ep->ExceptionRecord)); - } - else - { - _ftprintf(fFile, _T("######## EXCEPTION: 0x%8.8X at address: 0x%8.8X"), - ep->ExceptionRecord->ExceptionCode, - ep->ExceptionRecord->ExceptionAddress); - _ftprintf(fFile, _T(": %s %s\n"), GetExpectionCodeText(ep->ExceptionRecord->ExceptionCode), - GetAdditionalExpectionCodeText(ep->ExceptionRecord)); - } - - DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, 0, false, DUPLICATE_SAME_ACCESS ); - ShowStack( hThread, *(ep->ContextRecord), fFile); - CloseHandle( hThread ); - - if (g_CallstackOutputType == ACOutput_XML) - _ftprintf(fFile, _T("\n")); - - fclose(fFile); - - return status; -} // StackwalkFilter - -void ShowStack( HANDLE hThread, CONTEXT& c, LPCTSTR pszLogFile) -{ - FILE *fFile = stderr; // default to stderr - - if (pszLogFile != NULL) { // a filename is available - // Open the logfile - fFile = _tfopen(pszLogFile, _T("a")); - if (fFile != NULL) { // Is the file too big? - long size; - fseek(fFile, 0, SEEK_END); - size = ftell(fFile); // Get the size of the file - if (size >= LOG_FILE_MAX_SIZE) { - TCHAR *pszTemp = (TCHAR*) malloc(MAX_PATH); - // It is too big... - fclose(fFile); - _tcscpy(pszTemp, pszLogFile); - _tcscat(pszTemp, _T(".old")); - _tremove(pszTemp); // Remove an old file, if exists - _trename(pszLogFile, pszTemp); // rename the actual file - fFile = _tfopen(pszLogFile, _T("w")); // open new file - free(pszTemp); - } - } - } // if (pszLogFile != NULL) - if (fFile == NULL) { - fFile = stderr; - } - - ShowStack( hThread, c, fFile); - - fclose(fFile); -} - - -static void ShowStack( HANDLE hThread, CONTEXT& c, FILE *fLogFile) { - ShowStackRM(hThread, c, fLogFile, NULL, GetCurrentProcess()); -} - -static void ShowStackRM( HANDLE hThread, CONTEXT& c, FILE *fLogFile, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryFunction, HANDLE hSWProcess) { - // normally, call ImageNtHeader() and use machine info from PE header - DWORD imageType = IMAGE_FILE_MACHINE_I386; - HANDLE hProcess = GetCurrentProcess(); // hProcess normally comes from outside - int frameNum; // counts walked frames - DWORD offsetFromSymbol; // tells us how far from the symbol we were - DWORD offsetFromLine; // tells us how far from the line we were - DWORD symOptions; // symbol handler settings - - static IMAGEHLP_SYMBOL *pSym = NULL; - char undName[MAXNAMELEN]; // undecorated name - char undFullName[MAXNAMELEN]; // undecorated name with all shenanigans - IMAGEHLP_MODULE Module; - IMAGEHLP_LINE Line; - BOOL bXMLTagWrote; - - std::string symSearchPath; - - static bFirstTime = TRUE; - - // If no logfile is present, outpur to "stderr" - if (fLogFile == NULL) { - fLogFile = stderr; - } - - STACKFRAME s; // in/out stackframe - memset( &s, '\0', sizeof s ); - - if ( (g_bInitialized == FALSE) && (bFirstTime == TRUE) ) { - InitStackWalk(); - } - - if (g_bInitialized == FALSE) - { - // Could not init!!!! - bFirstTime = FALSE; - _ftprintf(fLogFile, _T("%lu: Stackwalker not initialized (or was not able to initialize)!\n"), g_dwShowCount); - return; - } - -// Critical section begin... - EnterCriticalSection(&g_csFileOpenClose); - - InterlockedIncrement((long*) &g_dwShowCount); // erhöhe counter - - - // NOTE: normally, the exe directory and the current directory should be taken - // from the target process. The current dir would be gotten through injection - // of a remote thread; the exe fir through either ToolHelp32 or PSAPI. - - if (pSym == NULL) { - pSym = (IMAGEHLP_SYMBOL *) malloc( IMGSYMLEN + MAXNAMELEN ); - if (!pSym) goto cleanup; // not enough memory... - } - - if (g_CallstackOutputType != ACOutput_XML) - { - _ftprintf(fLogFile, _T("%lu: "), g_dwShowCount); - WriteDateTime(fLogFile); - _ftprintf(fLogFile, _T("\n")); - } - - - if (bFirstTime) { - - CHAR *tt, *p; - - tt = (CHAR*) malloc(sizeof(CHAR) * TTBUFLEN); // Get the temporary buffer - if (!tt) goto cleanup; // not enough memory... - - // build symbol search path from: - symSearchPath = ""; - // current directory - if ( GetCurrentDirectoryA( TTBUFLEN, tt ) ) - symSearchPath += tt + std::string( ";" ); - // dir with executable - if ( GetModuleFileNameA( 0, tt, TTBUFLEN ) ) - { - for ( p = tt + strlen( tt ) - 1; p >= tt; -- p ) - { - // locate the rightmost path separator - if ( *p == '\\' || *p == '/' || *p == ':' ) - break; - } - // if we found one, p is pointing at it; if not, tt only contains - // an exe name (no path), and p points before its first byte - if ( p != tt ) // path sep found? - { - if ( *p == ':' ) // we leave colons in place - ++ p; - *p = '\0'; // eliminate the exe name and last path sep - symSearchPath += tt + std::string( ";" ); - } - } - // environment variable _NT_SYMBOL_PATH - if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", tt, TTBUFLEN ) ) - symSearchPath += tt + std::string( ";" ); - // environment variable _NT_ALTERNATE_SYMBOL_PATH - if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", tt, TTBUFLEN ) ) - symSearchPath += tt + std::string( ";" ); - // environment variable SYSTEMROOT - if ( GetEnvironmentVariableA( "SYSTEMROOT", tt, TTBUFLEN ) ) - symSearchPath += tt + std::string( ";" ); - - - - if ( symSearchPath.size() > 0 ) // if we added anything, we have a trailing semicolon - symSearchPath = symSearchPath.substr( 0, symSearchPath.size() - 1 ); - - // why oh why does SymInitialize() want a writeable string? - strncpy( tt, symSearchPath.c_str(), TTBUFLEN ); - tt[TTBUFLEN - 1] = '\0'; // if strncpy() overruns, it doesn't add the null terminator - - // init symbol handler stuff (SymInitialize()) - if ( ! pSI( hProcess, tt, false ) ) - { - if (g_CallstackOutputType != ACOutput_XML) - _ftprintf(fLogFile, _T("%lu: SymInitialize(): GetLastError = %lu\n"), g_dwShowCount, gle ); - if (tt) free( tt ); - goto cleanup; - } - - // SymGetOptions() - symOptions = pSGO(); - symOptions |= SYMOPT_LOAD_LINES; - symOptions &= ~SYMOPT_UNDNAME; - symOptions &= ~SYMOPT_DEFERRED_LOADS; - pSSO( symOptions ); // SymSetOptions() - - // Enumerate modules and tell imagehlp.dll about them. - // On NT, this is not necessary, but it won't hurt. - EnumAndLoadModuleSymbols( hProcess, GetCurrentProcessId(), fLogFile ); - - if (tt) - free( tt ); - } // bFirstTime = TRUE - bFirstTime = FALSE; - - // init STACKFRAME for first call - // Notes: AddrModeFlat is just an assumption. I hate VDM debugging. - // Notes: will have to be #ifdef-ed for Alphas; MIPSes are dead anyway, - // and good riddance. - s.AddrPC.Offset = c.Eip; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.Ebp; - s.AddrFrame.Mode = AddrModeFlat; - - memset( pSym, '\0', IMGSYMLEN + MAXNAMELEN ); - pSym->SizeOfStruct = IMGSYMLEN; - pSym->MaxNameLength = MAXNAMELEN; - - memset( &Line, '\0', sizeof Line ); - Line.SizeOfStruct = sizeof Line; - - memset( &Module, '\0', sizeof Module ); - Module.SizeOfStruct = sizeof Module; - - for ( frameNum = 0; ; ++ frameNum ) - { - // get next stack frame (StackWalk(), SymFunctionTableAccess(), SymGetModuleBase()) - // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can - // assume that either you are done, or that the stack is so hosed that the next - // deeper frame could not be found. - // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! - if ( ! pSW( imageType, hSWProcess, hThread, &s, NULL, ReadMemoryFunction, pSFTA, pSGMB, NULL ) ) - break; - - bXMLTagWrote = FALSE; - - if (g_CallstackOutputType == ACOutput_Advanced) - _ftprintf(fLogFile, _T("\n%lu: %3d"), g_dwShowCount, frameNum); - if ( s.AddrPC.Offset == 0 ) - { - // Special case: If we are here, we have no valid callstack entry! - switch(g_CallstackOutputType) - { - case ACOutput_Simple: - _ftprintf(fLogFile, _T("%lu: (-nosymbols- PC == 0)\n"), g_dwShowCount); - break; - case ACOutput_Advanced: - _ftprintf(fLogFile, _T(" (-nosymbols- PC == 0)\n")); - break; - case ACOutput_XML: - // TODO: .... - _ftprintf(fLogFile, _T("\n")); - break; - } - } - else - { - // we seem to have a valid PC - undName[0] = 0; - undFullName[0] = 0; - offsetFromSymbol = 0; - // show procedure info (SymGetSymFromAddr()) - if ( ! pSGSFA( hProcess, s.AddrPC.Offset, &offsetFromSymbol, pSym ) ) - { - if (g_CallstackOutputType == ACOutput_Advanced) - { - if ( gle != 487 ) - _ftprintf(fLogFile, _T(" SymGetSymFromAddr(): GetLastError = %lu\n"), gle ); - else - _ftprintf(fLogFile, _T("\n")); - } - } - else - { - // UnDecorateSymbolName() - pUDSN( pSym->Name, undName, MAXNAMELEN, UNDNAME_NAME_ONLY ); - pUDSN( pSym->Name, undFullName, MAXNAMELEN, UNDNAME_COMPLETE ); - if (g_CallstackOutputType == ACOutput_Advanced) - { - if (strlen(undName) > 0) - fprintf(fLogFile, " %s %+ld bytes\n", undName, (long) offsetFromSymbol ); - else - { - fprintf(fLogFile, " Sig: %s %+ld bytes\n", pSym->Name, (long) offsetFromSymbol ); - strcpy(undName, pSym->Name); - } - fprintf(fLogFile, "%lu: Decl: %s\n", g_dwShowCount, undFullName ); - } - } - //if (g_CallstackOutputType == ACOutput_XML) - // fprintf(fLogFile, "decl=\"%s\" decl_offset=\"%+ld\" ", SimpleXMLEncode(undName).c_str(), (long) offsetFromSymbol); - - // show line number info, NT5.0-method (SymGetLineFromAddr()) - offsetFromLine = 0; - if ( pSGLFA != NULL ) - { // yes, we have SymGetLineFromAddr() - if ( ! pSGLFA( hProcess, s.AddrPC.Offset, &offsetFromLine, &Line ) ) - { - if ( (gle != 487) && (frameNum > 0) ) // ignore error for first frame - { - if (g_CallstackOutputType == ACOutput_XML) - { - _ftprintf(fLogFile, _T("= 9 ? - case SymDia: - strcpy( ty, "DIA" ); - break;*/ - default: - _snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); - break; - } - - if (g_CallstackOutputType == ACOutput_XML) - { - // now, check if the XML-Entry is written... - if (bXMLTagWrote == FALSE) - { - _ftprintf(fLogFile, _T("\n")); // terminate the XML node - - } // we seem to have a valid PC - - // no return address means no deeper stackframe - if ( s.AddrReturn.Offset == 0 ) - { - // avoid misunderstandings in the printf() following the loop - SetLastError( 0 ); - break; - } - - } // for ( frameNum ) - - if ( (g_CallstackOutputType != ACOutput_XML) && (gle != 0) ) - _ftprintf(fLogFile, _T("\n%lu: StackWalk(): GetLastError = %lu\n"), g_dwShowCount, gle ); - -cleanup: - //if (pSym) free( pSym ); - if (fLogFile) { - _ftprintf(fLogFile, _T("\n\n")); - if (g_dwShowCount % 1000) - fflush(fLogFile); - } - - LeaveCriticalSection(&g_csFileOpenClose); -// Critical section end... -} // ShowStackRM diff --git a/client/win/Stackwalker.h b/client/win/Stackwalker.h deleted file mode 100755 index cfd93d778e..0000000000 --- a/client/win/Stackwalker.h +++ /dev/null @@ -1,51 +0,0 @@ -/*//////////////////////////////////////////////////////////////////////////// - * Project: - * Memory_and_Exception_Trace - * - * /////////////////////////////////////////////////////////////////////////// - * File: - * Stackwalker.h - * - * Remarks: - * - * - * Note: - * - * - * Author: - * Jochen Kalmbach - * - *//////////////////////////////////////////////////////////////////////////// - -#ifndef __STACKWALKER_H__ -#define __STACKWALKER_H__ - -// Only valid in the following environment: Intel platform, MS VC++ 5/6/7 -#ifndef _X86_ -#error Only INTEL envirnoments are supported! -#endif - -// Only MS VC++ 5 to 7 -#if (_MSC_VER < 1100) || (_MSC_VER > 1310) -#error Only MS VC++ 5/6/7 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! -#endif - -typedef enum eAllocCheckOutput -{ - ACOutput_Simple, - ACOutput_Advanced, - ACOutput_XML -}; - -// Make extern "C", so it will also work with normal C-Programs -#ifdef __cplusplus -extern "C" { -#endif - -extern DWORD StackwalkFilter( EXCEPTION_POINTERS *ep, DWORD status, LPCTSTR pszLogFile); - -#ifdef __cplusplus -} -#endif - -#endif // __STACKWALKER_H__ diff --git a/lib/parse.C b/lib/parse.C index 4eabaf575f..0d2bb7a4e9 100644 --- a/lib/parse.C +++ b/lib/parse.C @@ -120,8 +120,8 @@ void copy_stream(FILE* in, FILE* out) { char buf[1024]; int n, m; while (1) { - n = fread(buf, 1, 1024, in); - m = fwrite(buf, 1, n, out); + n = (int)fread(buf, 1, 1024, in); + m = (int)fwrite(buf, 1, n, out); if (n < 1024) break; } } diff --git a/lib/parse.h b/lib/parse.h index 71f78c8971..6f27cc3bf7 100644 --- a/lib/parse.h +++ b/lib/parse.h @@ -17,12 +17,10 @@ // Contributor(s): // -#ifndef _WIN32 #include #include #include -using std::string; -#endif +using namespace std; extern bool parse(char* , char* ); diff --git a/lib/util.C b/lib/util.C index 6389accaa5..faf3036294 100755 --- a/lib/util.C +++ b/lib/util.C @@ -293,7 +293,7 @@ void strip_whitespace(char *str) { strcpy(str, str+1); } while (1) { - n = strlen(str); + n = (int)strlen(str); if (n == 0) break; if (!isascii(str[n-1])) break; if (!isspace(str[n-1])) break; @@ -307,7 +307,7 @@ void strip_whitespace(string& str) { str.erase(0, 1); } while (1) { - n = str.length(); + n = (int)str.length(); if (n == 0) break; if (!isascii(str[n-1])) break; if (!isspace(str[n-1])) break; diff --git a/lib/xml_util.C b/lib/xml_util.C index 3dc9bc739c..adfddea442 100644 --- a/lib/xml_util.C +++ b/lib/xml_util.C @@ -19,6 +19,9 @@ // // Revision History // $Log$ +// Revision 1.28 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// // Revision 1.27 2004/01/22 17:57:41 davea // *** empty log message *** // @@ -32,12 +35,14 @@ // // #include "config.h" + #include #include #include #include #include #include + #include "std_fixes.h" #include "xml_util.h" @@ -562,7 +567,7 @@ std::string x_csv_encode_char(const unsigned char *bin, size_t nelements) { rv << ival << ','; if ((static_cast(rv.str().size())-lastlen-std::min(xml_indent_level,XML_MAX_INDENT))>73) { rv << std::endl << xml_indent(); - lastlen=rv.str().size(); + lastlen=(long)rv.str().size(); } } unsigned int ival=bin[i]; @@ -644,6 +649,9 @@ bool extract_xml_record(const std::string &field, const char *tag, std::string & // // $Log$ +// Revision 1.28 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// // Revision 1.27 2004/01/22 17:57:41 davea // *** empty log message *** // diff --git a/lib/xml_util.h b/lib/xml_util.h index 9945323558..5b397969f2 100644 --- a/lib/xml_util.h +++ b/lib/xml_util.h @@ -21,6 +21,9 @@ // // Revision History: // $Log$ +// Revision 1.20 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// // Revision 1.19 2004/02/05 05:32:22 quarl // *** empty log message *** // @@ -36,14 +39,19 @@ #ifndef _XML_UTIL_H_ #define _XML_UTIL_H_ + #include "config.h" + #include #include #include #include #include + #include "error_numbers.h" +using namespace std; + typedef enum tag_xml_encoding { _x_xml_entity=0, _x_xml_cdata, @@ -82,15 +90,15 @@ const char * const xml_encoding_names[]={ // the closing tag is written. class xml_ostream { public: - xml_ostream(std::ostream &o, const char *tag); + xml_ostream(ostream &o, const char *tag); ~xml_ostream(); template xml_ostream &operator <<(const T &t) { os << t; return *this; }; private: void write_head(); void write_foot(); - std::string my_tag; - std::ostream &os; + string my_tag; + ostream &os; }; // the xml_ofstream class is an ofstream. When the file is opened, @@ -100,16 +108,16 @@ class xml_ofstream { public: xml_ofstream(); explicit xml_ofstream(const char *filename, const char *tag, - std::ios_base::openmode m=std::ios_base::out|std::ios_base::binary); + ios_base::openmode m=ios_base::out|ios_base::binary); ~xml_ofstream(); void open(const char *p, const char *tag, - std::ios_base::openmode m=std::ios_base::out|std::ios_base::binary); + ios_base::openmode m=ios_base::out|ios_base::binary); void close(); private: void write_head(); void write_foot(); - std::string my_tag; - std::ofstream &os; + string my_tag; + ofstream &os; }; // the xml_istream class is an istream that can be constructed from @@ -118,13 +126,13 @@ class xml_ofstream { // for reading XML from stdin. class xml_istream { public: - explicit xml_istream(std::istream &i, const char *tag=0); + explicit xml_istream(istream &i, const char *tag=0); ~xml_istream(); - operator std::istream &() {return is;}; + operator istream &() {return is;}; private: void seek_head(); - std::string my_tag; - std::istream &is; + string my_tag; + istream &is; }; // the xml_ifstream class is an ifstream. When the file is opened, // the file pointer is set after the opening tag. An attempt to @@ -144,20 +152,20 @@ class xml_ifstream { public: xml_ifstream(); explicit xml_ifstream(const char *filename, const char *tag=0, - std::ios_base::openmode m=std::ios_base::in|std::ios_base::binary); + ios_base::openmode m=ios_base::in|ios_base::binary); ~xml_ifstream(); void open(const char *filename, const char *tag=0, - std::ios_base::openmode m=std::ios_base::in|std::ios_base::binary); + ios_base::openmode m=ios_base::in|ios_base::binary); xml_ifstream &seekg(pos_type p); - xml_ifstream &seekg(off_type o, std::ios_base::seekdir d); + xml_ifstream &seekg(off_type o, ios_base::seekdir d); pos_type tellg(); bool eof(); private: void seek_head(); - std::string my_tag; + string my_tag; pos_type xml_start; pos_type xml_end; - std::ifstream &ifs; + ifstream &ifs; }; #endif // 0 @@ -176,7 +184,7 @@ struct xml_entity { // change the xml indent level (number of spaces) by adding or subtracting // "i" spaces. return a string of spaces corresponding to the current xml // indent level. -std::string xml_indent(int i=0); +string xml_indent(int i=0); static const int XML_MAX_INDENT=40; extern int xml_indent_level; @@ -184,21 +192,21 @@ extern int xml_indent_level; // decode an XML character string. Return a the decoded string in a vector // (null not necessarily a terminator). //template -//std::vector xml_decode_string(const char *input, size_t length=0, +//vector xml_decode_string(const char *input, size_t length=0, // const char *encoding="x_xml_entity"); // do the same thing, but get the length and encoding type from the // xml tag properties. template -std::vector xml_decode_field(const std::string &input, const char *tag); +vector xml_decode_field(const string &input, const char *tag); // encode an XML character string. Return the encoded string. //template -//std::string xml_encode_string(const T *input, size_t n_elements=0, +//string xml_encode_string(const T *input, size_t n_elements=0, // xml_encoding encoding=_x_xml_entity); template -inline std::string xml_encode_string(const std::vector &input, +inline string xml_encode_string(const vector &input, xml_encoding encoding=_x_xml_entity) { return xml_encode_string(&(*(input.begin())),input.size(),encoding); } @@ -214,15 +222,15 @@ bool isencchar(char c); bool isencchar85(char c); template -std::string base64_encode(const T *tbin, size_t n_elements) { +string base64_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0, offset=0, nleft; const char crlf[]={0xa,0xd,0x0}; - std::string rv(""); + string rv(""); rv.reserve(nbytes*4/3+nbytes*2/57); char c[5]; - for (nleft = nbytes; nleft > 0; nleft -= 3) { + for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { int i; c[0] = (bin[offset]>>2) & 0x3f ; // 6 c[1] = (bin[offset]<<4) & 0x3f | ((bin[offset+1]>>4)&0xf); // 2+4 @@ -243,12 +251,12 @@ std::string base64_encode(const T *tbin, size_t n_elements) { } template -std::vector base64_decode(const char *data, size_t nbytes) { +vector base64_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2; const char cr=0xa,lf=0xd; char in[4],c[3]; int i; - std::vector rv; + vector rv; rv.reserve(nbytes*3/4); while (p<(data+nbytes)) { while (!isencchar(*p)) { @@ -257,7 +265,7 @@ std::vector base64_decode(const char *data, size_t nbytes) { eol=strchr(p,cr); eol2=strchr(p,lf); if (eol && eol2) { - eol=std::min(eol,eol2); + eol=min(eol,eol2); } for (;p<(eol-1);p+=4) { for ( i=0;i<4;i++) { @@ -283,16 +291,16 @@ std::vector base64_decode(const char *data, size_t nbytes) { for ( i=0;i<3;i++) rv.push_back(c[i]); } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::string base85_encode(const T *tbin, size_t n_elements) { +string base85_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0; const char crlf[]={0xa,0xd,0x0}; - std::string rv(""); + string rv(""); rv.reserve(nbytes*4/3+nbytes*2/57); char c[6]; int n_pads; @@ -324,19 +332,19 @@ std::string base85_encode(const T *tbin, size_t n_elements) { rv+=crlf; count=0; } - count+=strlen(c); + count+=(int)strlen(c); rv+=c; } return rv; } template -std::vector base85_decode(const char *data, size_t nbytes) { +vector base85_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2; const char cr=0xa,lf=0xd; unsigned long val; int npads; - std::vector rv; + vector rv; rv.reserve(nbytes*4/5); while (p<(data+nbytes)) { while (!isencchar85(*p)) { @@ -345,7 +353,7 @@ std::vector base85_decode(const char *data, size_t nbytes) { eol=strchr(p,cr); eol2=strchr(p,lf); if (eol && eol2) { - eol=std::min(eol,eol2); + eol=min(eol,eol2); } while (p base85_decode(const char *data, size_t nbytes) { if (p[i]!='_') break; npads++; } - for (i=0;i='0') && (p[i]<='9')) { val=p[i]-'0'; @@ -379,21 +387,21 @@ std::vector base85_decode(const char *data, size_t nbytes) { rv.push_back(val); } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::string x_setiathome_encode(const T *tbin, size_t n_elements) { +string x_setiathome_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0, offset=0, nleft; const char cr=0xa; - std::string rv(""); + string rv(""); rv.reserve(nbytes*4/3+nbytes*2/48); rv+="\n"; char c[5]; - for (nleft = nbytes; nleft > 0; nleft -= 3) { + for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { c[0] = bin[offset]&0x3f; // 6 c[1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 c[2] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 @@ -414,11 +422,11 @@ std::string x_setiathome_encode(const T *tbin, size_t n_elements) { template -std::vector x_setiathome_decode(const char *data, size_t nbytes) { +vector x_setiathome_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2; char in[4],c[3]; int i; - std::vector rv; + vector rv; rv.reserve(nbytes*3/4); while (p<(data+nbytes)) { while ((*p<0x20) || (*p>0x60)){ @@ -427,7 +435,7 @@ std::vector x_setiathome_decode(const char *data, size_t nbytes) { eol=strchr(p,'\n'); eol2=strchr(p,'\r'); if (eol && eol2) { - eol=std::min(eol,eol2); + eol=min(eol,eol2); } for (;p<(eol-1);p+=4) { memcpy(in,p,4); @@ -438,16 +446,16 @@ std::vector x_setiathome_decode(const char *data, size_t nbytes) { for ( i=0;i<3;i++) rv.push_back(c[i]); } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::string quoted_printable_encode(const T *tbin, size_t n_elements) { +string quoted_printable_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int line_len=0; const char crlf[]={'=',0xa,0xd,0x0}; - std::string rv(""); + string rv(""); rv.reserve(nbytes*4/3+nbytes*2/48); for (size_t i=0;i -std::vector quoted_printable_decode(const char* data, size_t nbytes) { - std::vector rv; +vector quoted_printable_decode(const char* data, size_t nbytes) { + vector rv; rv.reserve(strlen(data)); size_t i=0; while (i quoted_printable_decode(const char* data, size_t nbytes) { i+=3; } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::string x_hex_encode(const T *tbin, size_t n_elements) { +string x_hex_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); - std::string rv; + string rv; int count=0; rv.reserve(nbytes*2+nbytes*2/76); for (unsigned int i=0; i -std::vector x_hex_decode(const char *data, size_t nbytes) { - std::vector rv; +vector x_hex_decode(const char *data, size_t nbytes) { + vector rv; rv.reserve(nbytes/2); unsigned int i=0; while (i x_hex_decode(const char *data, size_t nbytes) { i+=2; rv.push_back(static_cast(c)); } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } -std::string x_csv_encode_char(const unsigned char *bin, size_t nelements); +string x_csv_encode_char(const unsigned char *bin, size_t nelements); template -std::string x_csv_encode(const T *bin, size_t nelements) { - std::ostringstream rv(""); +string x_csv_encode(const T *bin, size_t nelements) { + ostringstream rv(""); long lastlen=0,i; bool ischar=(sizeof(T)==1); - rv << std::endl << xml_indent(2); + rv << endl << xml_indent(2); if (ischar) return x_csv_encode_char((const unsigned char *)bin, nelements); for (i=0;i<(nelements-1);i++) { rv << bin[i] << ','; - if ((static_cast(rv.str().size())-lastlen-std::min(xml_indent_level,XML_MAX_INDENT))>73) { - rv << std::endl << xml_indent(); - lastlen=rv.str().size(); + if ((static_cast(rv.str().size())-lastlen-min(xml_indent_level,XML_MAX_INDENT))>73) { + rv << endl << xml_indent(); + lastlen=(long)rv.str().size(); } } rv << bin[i] << "\n" << xml_indent(-2); @@ -549,13 +557,13 @@ std::string x_csv_encode(const T *bin, size_t nelements) { template -std::vector x_csv_decode(const char *data, size_t nbytes) { - std::vector rv; +vector x_csv_decode(const char *data, size_t nbytes) { + vector rv; while (!isdigit(*data)) { data++; nbytes--; } - std::istringstream in(std::string(data,nbytes)); + istringstream in(string(data,nbytes)); bool ischar=(sizeof(T)==1); while (in) { @@ -578,18 +586,18 @@ std::vector x_csv_decode(const char *data, size_t nbytes) { } -std::string encode_char(unsigned char c); +string encode_char(unsigned char c); unsigned char decode_char(const char *s); template -std::vector x_xml_entity_decode(const char *input, size_t length) { +vector x_xml_entity_decode(const char *input, size_t length) { unsigned int i; char c; if (!length) { // We're going to decode until we see a null. Including the null. length=strlen((const char *)input); } - std::vector rv; + vector rv; char *p; rv.reserve(length); for (i=0; i x_xml_entity_decode(const char *input, size_t length) { rv.push_back(input[i]); } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::string x_xml_entity_encode(const T *tbin, size_t n_elements) { +string x_xml_entity_encode(const T *tbin, size_t n_elements) { size_t length=n_elements*sizeof(T); const unsigned char *input=(const unsigned char *)(tbin); unsigned int i; - std::string rv; + string rv; rv.reserve(length); for (i=0; i -std::string x_xml_values_encode(const T *bin, size_t n_elements) { - std::ostringstream rv(""); +string x_xml_values_encode(const T *bin, size_t n_elements) { + ostringstream rv(""); unsigned int i; for (i=0;i -std::vector x_xml_values_decode(const char *data, size_t length) { - std::istringstream r(std::string(data,length)); - std::vector rv; +vector x_xml_values_decode(const char *data, size_t length) { + istringstream r(string(data,length)); + vector rv; T t; while (!r.eof()) { r >> t ; @@ -664,11 +672,11 @@ std::vector x_xml_values_decode(const char *data, size_t length) { } template -std::string x_xml_cdata_encode(const T *tbin, size_t n_elements) { +string x_xml_cdata_encode(const T *tbin, size_t n_elements) { size_t length=n_elements*sizeof(T); const unsigned char *input=(const unsigned char *)(tbin); unsigned int i; - std::string rv("0x1f) { @@ -694,14 +702,14 @@ std::string x_xml_cdata_encode(const T *tbin, size_t n_elements) { } template -std::vector x_xml_cdata_decode(const char *input, size_t length) { +vector x_xml_cdata_decode(const char *input, size_t length) { unsigned int i; char c; if (!length) { // We're going to decode until we see a null. Including the null. length=strlen(input); } - std::vector rv; + vector rv; char *p; rv.reserve(length); for (i=0; i x_xml_cdata_decode(const char *input, size_t length) { rv.push_back(input[i]); } } - return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); + return vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template -std::vector x_uudecode(const char *data, size_t nbytes) { - std::vector rv; +vector x_uudecode(const char *data, size_t nbytes) { + vector rv; return rv; } template -std::string x_uuencode(const T *data, size_t nbytes) { - std::string rv; +string x_uuencode(const T *data, size_t nbytes) { + string rv; return rv; } template -std::vector xml_decode_string(const char *input, +vector xml_decode_string(const char *input, size_t length=0, const char *encoding="x_xml_entity") { int i=_x_xml_entity; do { @@ -772,37 +780,37 @@ std::vector xml_decode_string(const char *input, return x_uudecode(input,length); case _8bit: case _binary: - return std::vector((const T *)input,(const T *)input+length/sizeof(T)); + return vector((const T *)input,(const T *)input+length/sizeof(T)); default: return x_xml_entity_decode(input,length); } } template -std::vector xml_decode_field(const std::string &input, const char *tag) { - std::string start_tag("<"),end_tag(" xml_decode_field(const string &input, const char *tag) { + string start_tag("<"),end_tag("',start)+1; if (!length) { - length=endt-start; + length=(unsigned int)endt - (unsigned int)start; } return (xml_decode_string(&(input[start]),length,encoding)); } template -std::string xml_encode_string(const T *input, +string xml_encode_string(const T *input, size_t length=0, xml_encoding encoding=_x_xml_entity) { switch (encoding) { case _x_xml_entity: @@ -827,19 +835,22 @@ std::string xml_encode_string(const T *input, return x_uuencode(input,length); case _8bit: case _binary: - return std::string((const char *)(input),length*sizeof(T)); + return string((const char *)(input),length*sizeof(T)); default: return x_xml_entity_encode(input,length); } } extern bool xml_match_tag(const char*, const char*); -extern bool xml_match_tag(const std::string &, const char*); -extern bool extract_xml_record(const std::string &field, const char *tag, std::string &record); +extern bool xml_match_tag(const string &, const char*); +extern bool extract_xml_record(const string &field, const char *tag, string &record); #endif // // $Log$ +// Revision 1.20 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// // Revision 1.19 2004/02/05 05:32:22 quarl // *** empty log message *** // diff --git a/win_build/boinc_cli.vcproj b/win_build/boinc_cli.vcproj index 76228b9dc5..58f61b9d94 100644 --- a/win_build/boinc_cli.vcproj +++ b/win_build/boinc_cli.vcproj @@ -3,6 +3,7 @@ ProjectType="Visual C++" Version="7.10" Name="boinc_cli" + RootNamespace="boinc_cli" SccProjectName="" SccLocalPath=""> @@ -21,11 +22,12 @@ + RelativePath="..\api\win\Stackwalker.cpp"> @@ -1172,6 +1178,9 @@ + + diff --git a/win_build/boinc_dll.vcproj b/win_build/boinc_dll.vcproj index a8edc70737..b798168ca1 100644 --- a/win_build/boinc_dll.vcproj +++ b/win_build/boinc_dll.vcproj @@ -25,6 +25,7 @@ BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="2" + PrecompiledHeaderThrough="..\client\StdAfx.h" PrecompiledHeaderFile=".\Build\Debug\boinc_dll\obj/boinc_dll.pch" AssemblerListingLocation=".\Build\Debug\boinc_dll\obj/" ObjectFile=".\Build\Debug\boinc_dll\obj/" @@ -37,9 +38,11 @@ Name="VCCustomBuildTool"/> - - - - - - + RelativePath="..\api\win\Stackwalker.cpp"> @@ -1359,7 +1343,7 @@ RelativePath="..\client\ss_logic.h"> + RelativePath="..\api\win\Stackwalker.h"> diff --git a/win_build/boinc_ss.vcproj b/win_build/boinc_ss.vcproj index b9d9e14611..cab0c424e5 100644 --- a/win_build/boinc_ss.vcproj +++ b/win_build/boinc_ss.vcproj @@ -21,11 +21,12 @@