Commit e8bf268e authored by Jan Möbius's avatar Jan Möbius
Browse files

StackWalker added for windows. TODO: Add License Block

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@17427 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 5714af78
......@@ -38,6 +38,12 @@ else (APPLE)
)
endif(APPLE)
if (WIN32)
SET(WIN_EXTRA_DIRS "../StackWalker" )
else(WIN32)
SET(WIN_EXTRA_DIRS "")
endif(WIN32)
# source code directories
set (directories
..
......@@ -62,6 +68,7 @@ set (directories
../widgets/stereoSettingsWidget
../widgets/postProcessorWidget
../widgets/rendererWidget
${WIN_EXTRA_DIRS}
)
# collect all header,source and ui files
......
......@@ -68,64 +68,36 @@
#include <execinfo.h>
#endif
#ifdef WIN32
#ifndef NDEBUG
#define WIN_GET_DEBUG_CONSOLE
#endif
#endif
#ifdef USE_OPENMP
#include <omp.h>
#endif
#ifdef WIN32
#include "StackWalker/StackWalker.hh"
class StackWalkerToConsole : public StackWalker
{
protected:
virtual void OnOutput(LPCSTR szText)
{
printf("%s",szText);
}
};
#endif
// Includes for windows debugging console
#ifdef WIN32
#ifdef WIN_GET_DEBUG_CONSOLE
#include <fcntl.h>
#include <io.h>
#endif
// #ifndef WIN32
//
// #include <sys/resource.h>
//
// void getSystemInfo() {
//
// struct rusage resource_usage;
// if (getrusage(RUSAGE_SELF, &resource_usage))
// {
// //error - call to getrusage failed - handle itf
// std::cerr << "Unable to get process information" << std::endl;
// }
// else
// {
// std::cerr << "Got process information" << std::endl;
// std::cerr << "Maximum resident size : " << resource_usage.ru_maxrss << std::endl;
// std::cerr << "Shared Memory size : " << resource_usage.ru_ixrss << std::endl;
// std::cerr << "Unshared Data size : " << resource_usage.ru_idrss << std::endl;
// std::cerr << "Unshared Stack size : " << resource_usage.ru_isrss << std::endl;
// std::cerr << "Page faults : " << resource_usage.ru_majflt << std::endl;
// std::cerr << "Block input operations : " << resource_usage.ru_inblock << std::endl;
// std::cerr << "Block output operations : " << resource_usage.ru_oublock << std::endl;
//
//
// //call successful
// //get values for resident set size (ru_idrss)
// //swap space is probably not accounted for but thats all what this
// //call gives you...
// struct rusage {
// struct timeval ru_utime; /* user time used */
// struct timeval ru_stime; /* system time used */
// long ru_minflt; /* page reclaims */
// long ru_nswap; /* swaps */
// long ru_msgsnd; /* messages sent */
// long ru_msgrcv; /* messages received */
// long ru_nsignals; /* signals received */
// long ru_nvcsw; /* voluntary context switches */
// long ru_nivcsw; /* involuntary context switches */
// };
// }
// }
// #endif
#endif
enum {OPT_HELP , OPT_STEREO, OPT_BATCH ,OPT_CONSOLE_LOG , OPT_DEBUGGING, OPT_FULLSCREEN,
......@@ -199,6 +171,8 @@ void backtrace()
}
#endif
void segfaultHandling (int) {
// prevent infinite recursion if segfaultHandling() causes another segfault
......@@ -221,10 +195,18 @@ void segfaultHandling (int) {
#endif
#ifdef WIN32
StackWalkerToConsole sw;
sw.ShowCallstack();
#endif
std::abort();
}
#ifdef WIN32
#ifdef WIN_GET_DEBUG_CONSOLE
void getConsole() {
//Create a console for this application
AllocConsole();
......@@ -248,6 +230,7 @@ void segfaultHandling (int) {
setvbuf(stdin, NULL, _IONBF, 0);
}
#endif
#endif
bool openPolyMeshes = false;
bool remoteControl = false;
......@@ -349,11 +332,11 @@ int main(int argc, char **argv)
OpenFlipper::Options::windowTitle(TOSTRING(PRODUCT_STRING)" v" + OpenFlipper::Options::coreVersion());
#ifdef WIN32
#ifndef NDEBUG
getConsole();
#endif
#endif
#ifdef WIN32
#ifdef WIN_GET_DEBUG_CONSOLE
getConsole();
#endif
#endif
if ( !OpenFlipper::Options::nogui() ) {
......
/**********************************************************************
*
* StackWalker.cpp
* http://stackwalker.codeplex.com/
*
*
* History:
* 2005-07-27 v1 - First public release on http://www.codeproject.com/
* http://www.codeproject.com/threads/StackWalker.asp
* 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack
* (to simplify the usage)
* 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL
* (should also be enough)
* - Changed to compile correctly with the PSDK of VC7.0
* (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined:
* it uses LPSTR instead of LPCSTR as first paremeter)
* - Added declarations to support VC5/6 without using 'dbghelp.h'
* - Added a 'pUserData' member to the ShowCallstack function and the
* PReadProcessMemoryRoutine declaration (to pass some user-defined data,
* which can be used in the readMemoryFunction-callback)
* 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default
* - Added example for doing an exception-callstack-walking in main.cpp
* (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268)
* 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse!
* 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag
* http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx
* Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN"
* http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx
* Fixed Bug: Compiling with "/Wall"
* http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx
* Fixed Bug: Now checking SymUseSymSrv
* http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx
* Fixed Bug: Support for recursive function calls
* http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx
* Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32"
* http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx
* Fixed Bug: SymDia is number 7, not 9!
* 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8!
* Thanks to Teajay which reported the bug...
* http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx
* 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory
* Thanks to Luiz Salamon which reported this "bug"...
* http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx
* 2009-04-10 v9 License slihtly corrected (<ORGANIZATION> replaced)
* 2009-11-01 v10 Moved to http://stackwalker.codeplex.com/
* 2009-11-02 v11 Now try to use IMAGEHLP_MODULE64_V3 if available
* 2010-04-15 v12 Added support for VS2010 RTM
* 2010-05-25 v13 Now using secure MyStrcCpy. Thanks to luke.simon:
* http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx
* 2013-01-07 v14 Runtime Check Error VS2010 Debug Builds fixed:
* http://stackwalker.codeplex.com/workitem/10511
*
*
* LICENSE (http://www.opensource.org/licenses/bsd-license.php)
*
* Copyright (c) 2005-2013, Jochen Kalmbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of Jochen Kalmbach nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "version.lib") // for "VerQueryValue"
#pragma warning(disable:4826)
#include "StackWalker.hh"
// If VC7 and later, then use the shipped 'dbghelp.h'-file
#pragma pack(push,8)
#if _MSC_VER >= 1300
#include <dbghelp.h>
#else
// inline the important dbghelp.h-declarations...
typedef enum {
SymNone = 0,
SymCoff,
SymCv,
SymPdb,
SymExport,
SymDeferred,
SymSym,
SymDia,
SymVirtual,
NumSymTypes
} SYM_TYPE;
typedef struct _IMAGEHLP_LINE64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
PVOID Key; // internal
DWORD LineNumber; // line number in file
PCHAR FileName; // full filename
DWORD64 Address; // first instruction of line
} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
typedef struct _IMAGEHLP_MODULE64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
DWORD64 BaseOfImage; // base load address of module
DWORD ImageSize; // virtual size of the loaded module
DWORD TimeDateStamp; // date/time stamp from pe header
DWORD CheckSum; // checksum from the pe header
DWORD NumSyms; // number of symbols in the symbol table
SYM_TYPE SymType; // type of symbols loaded
CHAR ModuleName[32]; // module name
CHAR ImageName[256]; // image name
CHAR LoadedImageName[256]; // symbol file name
} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
typedef struct _IMAGEHLP_SYMBOL64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
DWORD64 Address; // virtual address including dll base address
DWORD Size; // estimated size of symbol, can be zero
DWORD Flags; // info about the symbols, see the SYMF defines
DWORD MaxNameLength; // maximum size of symbol name in 'Name'
CHAR Name[1]; // symbol name (null terminated string)
} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
typedef enum {
AddrMode1616,
AddrMode1632,
AddrModeReal,
AddrModeFlat
} ADDRESS_MODE;
typedef struct _tagADDRESS64 {
DWORD64 Offset;
WORD Segment;
ADDRESS_MODE Mode;
} ADDRESS64, *LPADDRESS64;
typedef struct _KDHELP64 {
DWORD64 Thread;
DWORD ThCallbackStack;
DWORD ThCallbackBStore;
DWORD NextCallback;
DWORD FramePointer;
DWORD64 KiCallUserMode;
DWORD64 KeUserCallbackDispatcher;
DWORD64 SystemRangeStart;
DWORD64 Reserved[8];
} KDHELP64, *PKDHELP64;
typedef struct _tagSTACKFRAME64 {
ADDRESS64 AddrPC; // program counter
ADDRESS64 AddrReturn; // return address
ADDRESS64 AddrFrame; // frame pointer
ADDRESS64 AddrStack; // stack pointer
ADDRESS64 AddrBStore; // backing store pointer
PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
DWORD64 Params[4]; // possible arguments to the function
BOOL Far; // WOW far call
BOOL Virtual; // is this a virtual frame?
DWORD64 Reserved[3];
KDHELP64 KdHelp;
} STACKFRAME64, *LPSTACKFRAME64;
typedef
BOOL
(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
HANDLE hProcess,
DWORD64 qwBaseAddress,
PVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead
);
typedef
PVOID
(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
HANDLE hProcess,
DWORD64 AddrBase
);
typedef
DWORD64
(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
HANDLE hProcess,
DWORD64 Address
);
typedef
DWORD64
(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
HANDLE hProcess,
HANDLE hThread,
LPADDRESS64 lpaddr
);
#define SYMOPT_CASE_INSENSITIVE 0x00000001
#define SYMOPT_UNDNAME 0x00000002
#define SYMOPT_DEFERRED_LOADS 0x00000004
#define SYMOPT_NO_CPP 0x00000008
#define SYMOPT_LOAD_LINES 0x00000010
#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
#define SYMOPT_LOAD_ANYTHING 0x00000040
#define SYMOPT_IGNORE_CVREC 0x00000080
#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
#define SYMOPT_EXACT_SYMBOLS 0x00000400
#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
#define SYMOPT_PUBLICS_ONLY 0x00004000
#define SYMOPT_NO_PUBLICS 0x00008000
#define SYMOPT_AUTO_PUBLICS 0x00010000
#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
#define SYMOPT_SECURE 0x00040000
#define SYMOPT_DEBUG 0x80000000
#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
#endif // _MSC_VER < 1300
#pragma pack(pop)
// Some missing defines (for VC5/6):
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
// secure-CRT_functions are only available starting with VC8
#if _MSC_VER < 1400
#define strcpy_s(dst, len, src) strcpy(dst, src)
#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src)
#define strcat_s(dst, len, src) strcat(dst, src)
#define _snprintf_s _snprintf
#define _tcscat_s _tcscat
#endif
static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
{
if (nMaxDestSize <= 0) return;
if (strlen(szSrc) < nMaxDestSize)
{
strcpy_s(szDest, nMaxDestSize, szSrc);
}
else
{
strncpy_s(szDest, nMaxDestSize, szSrc, nMaxDestSize);
szDest[nMaxDestSize-1] = 0;
}
} // MyStrCpy
// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
#define USED_CONTEXT_FLAGS CONTEXT_FULL
class StackWalkerInternal
{
public:
StackWalkerInternal(StackWalker *parent, HANDLE hProcess)
{
m_parent = parent;
m_hDbhHelp = NULL;
pSC = NULL;
m_hProcess = hProcess;
m_szSymPath = NULL;
pSFTA = NULL;
pSGLFA = NULL;
pSGMB = NULL;
pSGMI = NULL;
pSGO = NULL;
pSGSFA = NULL;
pSI = NULL;
pSLM = NULL;
pSSO = NULL;
pSW = NULL;
pUDSN = NULL;
pSGSP = NULL;
}
~StackWalkerInternal()
{
if (pSC != NULL)
pSC(m_hProcess); // SymCleanup
if (m_hDbhHelp != NULL)
FreeLibrary(m_hDbhHelp);
m_hDbhHelp = NULL;
m_parent = NULL;
if(m_szSymPath != NULL)
free(m_szSymPath);
m_szSymPath = NULL;
}
BOOL Init(LPCSTR szSymPath)
{
if (m_parent == NULL)
return FALSE;
// Dynamically load the Entry-Points for dbghelp.dll:
// First try to load the newsest one from
TCHAR szTemp[4096];
// But before wqe do this, we first check if the ".local" file exists
if (GetModuleFileName(NULL, szTemp, 4096) > 0)
{
_tcscat_s(szTemp, _T(".local"));
if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES)
{
// ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows"
// Ok, first try the new path according to the archtitecture:
#ifdef _M_IX86
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll"));
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
}
}
#elif _M_X64
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll"));
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
}
}
#elif _M_IA64
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll"));
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
}
}
#endif
// If still not found, try the old directories...
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll"));
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
}
}
#if defined _M_X64 || defined _M_IA64
// Still not found? Then try to load the (old) 64-Bit version:
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
}
}
#endif
}
}
if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one
m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") );
if (m_hDbhHelp == NULL)
return FALSE;
pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" );
pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" );
pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" );
pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" );
pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" );
pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" );
pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" );
pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" );
pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" );
pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" );
pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" );
pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" );
pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" );
if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL ||
pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL ||
pSW == NULL || pUDSN == NULL || pSLM == NULL )
{
FreeLibrary(m_hDbhHelp);
m_hDbhHelp = NULL;
pSC = NULL;
return FALSE;
}
// SymInitialize
if (szSymPath != NULL)
m_szSymPath = _strdup(szSymPath);
if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE)
this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
DWORD symOptions = this->pSGO(); // SymGetOptions
symOptions |= SYMOPT_LOAD_LINES;
symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
//symOptions |= SYMOPT_NO_PROMPTS;
// SymSetOptions
symOptions = this->pSSO(symOptions);
char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
if (this->pSGSP != NULL)
{
if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0);
}
char szUserName[1024] = {0};
DWORD dwSize = 1024;
GetUserNameA(szUserName, &dwSize);
this->m_parent->OnSymInit(buf, symOptions, szUserName);
return TRUE;
}
StackWalker *m_parent;
HMODULE m_hDbhHelp;
HANDLE m_hProcess;
LPSTR m_szSymPath;
#pragma pack(push,8)
typedef struct IMAGEHLP_MODULE64_V3 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
DWORD64 BaseOfImage; // base load address of module
DWORD ImageSize; // virtual size of the loaded module
DWORD TimeDateStamp; // date/time stamp from pe header
DWORD CheckSum; // checksum from the pe header
DWORD NumSyms; // number of symbols in the symbol table
SYM_TYPE SymType; // type of symbols loaded
CHAR ModuleName[32]; // module name
CHAR ImageName[256]; // image name
CHAR LoadedImageName[256]; // symbol file name
// new elements: 07-Jun-2002
CHAR LoadedPdbName[256]; // pdb file name
DWORD CVSig; // Signature of the CV record in the debug directories
CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
DWORD PdbSig; // Signature of PDB
GUID PdbSig70; // Signature of PDB (VC 7 and up)
DWORD PdbAge; // DBI age of pdb
BOOL PdbUnmatched; // loaded an unmatched pdb
BOOL DbgUnmatched; // loaded an unmatched dbg
BOOL LineNumbers; // we have line number information
BOOL GlobalSymbols; // we have internal symbol information
BOOL TypeInfo; // we have type information
// new elements: 17-Dec-2003
BOOL SourceIndexed; // pdb supports source server
BOOL Publics; // contains public symbols
};
typedef struct IMAGEHLP_MODULE64_V2 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
DWORD64 BaseOfImage; // base load address of module
DWORD ImageSize; // virtual size of the loaded module
DWORD TimeDateStamp; // date/time stamp from pe header
DWORD CheckSum; // checksum from the pe header
DWORD NumSyms; // number of symbols in the symbol table
SYM_TYPE SymType; // type of symbols loaded
CHAR ModuleName[32]; // module name
CHAR ImageName[256]; // image name
CHAR LoadedImageName[256]; // symbol file name
};
#pragma pack(pop)