/* * This is a part of the BugTrap package. * Copyright (c) 2005-2009 IntelleSoft. * All rights reserved. * * Description: Low-level wrapper for Debug Help API. * Author: Maksim Pyatkovskiy. * Note: Portions of this code are based on Bugslayer code developed by John Robbins. * * This source code is only intended as a supplement to the * BugTrap package reference and related electronic documentation * provided with the product. See these sources for detailed * information regarding the BugTrap package. */ #pragma once #include "EnumProcess.h" #include "StrStream.h" #include "Encoding.h" #include "XmlWriter.h" #include "SmartPtr.h" #include "InterfacePtr.h" #ifdef _MANAGED #include "NetThunks.h" #endif /// Type definition of pointer to SymGetOptions() function. typedef DWORD (WINAPI *PFSymGetOptions)(VOID); /// Type definition of pointer to SymSetOptions() function. typedef DWORD (WINAPI *PFSymSetOptions)(DWORD SymOptions); /// Type definition of pointer to SymInitialize() function. typedef BOOL (WINAPI *PFSymInitialize)(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess); /// Type definition of pointer to SymCleanup() function. typedef BOOL (WINAPI *PFSymCleanup)(HANDLE hProcess); /// Type definition of pointer to SymGetModuleBase64() function. typedef DWORD64 (WINAPI *PFSymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr); /// Type definition of pointer to SymFromAddr() function. typedef BOOL (WINAPI *PFSymFromAddr)(HANDLE hProcess, DWORD64 dwAddr, PDWORD64 pdwDisplacement, PSYMBOL_INFO Symbol); /// Type definition of pointer to SymGetLineFromAddr64() function. typedef BOOL (WINAPI *PFSymGetLineFromAddr64)(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line); /// Type definition of pointer to StackWalk64() function. typedef BOOL (WINAPI *PFStackWalk64)(DWORD dwMachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); /// Type definition of pointer to SymFunctionTableAccess64() function. typedef PVOID (WINAPI *PFSymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase); /// Type definition of pointer to MiniDumpWriteDump() function. typedef BOOL (WINAPI *PFMiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserEncoderParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); /// Opens an existing thread object. typedef HANDLE (WINAPI *PFOpenThread)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); /// Low-level wrapper for Debug Help API. class CSymEngine { public: /// Type of exception. enum EXCEPTION_TYPE { /// Not an exception. NO_EXCEPTION, /// Win32 exception. WIN32_EXCEPTION, /// C++ exception. CPP_EXCEPTION, #ifdef _MANAGED /// .NET exception. NET_EXCEPTION #endif }; /// Screen-shot object. class CScreenShot { public: /// Create the object. CScreenShot(void); /// Destroy the object. ~CScreenShot(void); /// Write screen-shot to file. BOOL WriteScreenShot(PCTSTR pszFileName); private: /// Protects the class from being accidentally copied. CScreenShot(const CScreenShot& rScreenShot); /// Protects the class from being accidentally copied. CScreenShot& operator=(const CScreenShot& rScreenShot); /// Per-monitor bitmap information. struct CBitmapInfo { public: /// Initialize an object. CBitmapInfo(void); /// De-initialize the object. ~CBitmapInfo(void); /// Free allocated memory; reset all member variables. void Free(void); /// Bitmap information. PBITMAPINFO m_pBmpInfo; /// Bitmap bits. PBYTE m_pBitsArray; /// Bitmap header size. DWORD m_dwBmpHdrSize; /// Image size. DWORD m_dwBitsArraySize; private: /// Destroy allocated objects. void Destroy(void); }; /// An array of bitmaps. CBitmapInfo* m_arrBitmaps; /// Number of monitors. DWORD m_dwNumMonitors; }; /// Smart pointer to the screen-shot. typedef CSmartPtr > CScreenShotPtr; /// Symbolic engine parameters. class CEngineParams { public: /// Initialize member variables. CEngineParams(void); /// Initialize member variables. CEngineParams(PEXCEPTION_POINTERS pExceptionPointers, EXCEPTION_TYPE eExceptionType); /// Current exception information. PEXCEPTION_POINTERS m_pExceptionPointers; /// COM error information. CInterfacePtr m_pErrorInfo; /// System error code. DWORD m_dwLastError; /// Type of the exception. EXCEPTION_TYPE m_eExceptionType; /// Date and time of the crash. SYSTEMTIME m_DateTime; /// Screen shot data. CScreenShotPtr m_pScreenShot; private: /// Make a screen shot. void MakeScreenShot(void); }; /// Stack entry information. struct CStackTraceEntry { /// Initialize data members. CStackTraceEntry(void); /// Module name that contains the entry. TCHAR m_szModule[MAX_PATH]; /// Address of current instruction. TCHAR m_szAddress[32]; /// Function where current instruction is located. TCHAR m_szFunctionName[512]; /// Byte offset from the beginning of the function. TCHAR m_szFunctionOffset[32]; /// User-friendly function name and offset. TCHAR m_szFunctionInfo[512]; /// Name of source file that contains the entry. TCHAR m_szSourceFile[MAX_PATH]; /// Number of line in source file. TCHAR m_szLineNumber[16]; /// Byte offset from the beginning of the line. TCHAR m_szLineOffset[32]; /// User-friendly line number and offset. TCHAR m_szLineInfo[64]; }; private: /// Context record of stack walk operations. struct CStackWalkContext { /// Initialize the object. CStackWalkContext(void); /// Current stack frame information used by stack tracing. STACKFRAME64 m_stFrame; /// Current context information used by stack tracing. CONTEXT m_context; /// Handle of examined thread. HANDLE m_hThread; }; /// Operating system information. struct COsInfo { /// Initialize the object. COsInfo(void); /// Windows version. PCTSTR m_pszWinVersion; /// Service pack version. TCHAR m_szSPVersion[128]; /// Build number. TCHAR m_szBuildNumber[16]; #ifdef _MANAGED /// CLR Version. WCHAR m_szNetVersion[64]; #endif }; /// Error information. struct CErrorInfo : public CStackTraceEntry { /// Initialize the object. CErrorInfo(void); /// What happened? PCTSTR m_pszWhat; /// Process file name. TCHAR m_szProcessName[MAX_PATH]; /// Process ID. TCHAR m_szProcessID[16]; }; /// CPUs information. struct CCpusInfo { /// Initialize the object. CCpusInfo(void); /// Processors architecture. PCTSTR m_pszCpuArch; /// Number of processors. DWORD m_dwNumCpus; }; /// CPU information. struct CCpuInfo { /// Initialize the object. CCpuInfo(void); /// Processor identifier. TCHAR m_szCpuId[128]; /// Processor speed. TCHAR m_szCpuSpeed[16]; /// Processor description. TCHAR m_szCpuDescription[128]; }; /// Memory information. struct CMemInfo { /// Initialize the object. CMemInfo(void); /// Current memory load TCHAR m_szMemoryLoad[8]; /// Total physical memory TCHAR m_szTotalPhys[16]; /// Available physical memory TCHAR m_szAvailPhys[16]; /// Total page file memory TCHAR m_szTotalPageFile[16]; /// Available page file memory TCHAR m_szAvailPageFile[16]; }; /// System error information. struct CSysErrorInfo { public: /// Initialize the object. CSysErrorInfo(void); /// De-initialize the object. ~CSysErrorInfo(void); /// Copy the object. CSysErrorInfo(const CSysErrorInfo& rErrorInfo); /// Copy the object. CSysErrorInfo& operator=(const CSysErrorInfo& rErrorInfo); /// Last error code. TCHAR m_szErrorCode[16]; /// Error description. PTSTR m_pszMessageBuffer; private: /// Free member variables. void FreeData(void); /// Copy member variables. void CopyData(const CSysErrorInfo& rErrorInfo); }; /// COM error information. struct CComErrorInfo { /// A textual description of the error. CStrHolder m_strDescription; /// The path of the help file that describes the error. CStrHolder m_strHelpFile; /// The programmatic identifier (ProgID) for the class or application that returned the error. CStrHolder m_strSource; /// The globally unique identifier (GUID) for the interface that defined the error. CStrHolder m_strGuid; }; /// Keeps registers values in string format. struct CRegistersValues { /// Initialize the object. CRegistersValues(void); #if defined _M_IX86 /// EAX register. TCHAR m_szEax[16]; /// EBX register. TCHAR m_szEbx[16]; /// ECX register. TCHAR m_szEcx[16]; /// EDX register. TCHAR m_szEdx[16]; /// ESI register. TCHAR m_szEsi[16]; /// EDI register. TCHAR m_szEdi[16]; /// ESP register. TCHAR m_szEsp[16]; /// EBP register. TCHAR m_szEbp[16]; /// EIP register. TCHAR m_szEip[16]; /// CS register. TCHAR m_szSegCs[16]; /// DS register. TCHAR m_szSegDs[16]; /// SS register. TCHAR m_szSegSs[16]; /// ES register. TCHAR m_szSegEs[16]; /// FS register. TCHAR m_szSegFs[16]; /// GS register. TCHAR m_szSegGs[16]; /// EFLAGS register. TCHAR m_szEFlags[16]; #elif defined _M_X64 /// RAX register. TCHAR m_szRax[32]; /// RBX register. TCHAR m_szRbx[32]; /// RCX register. TCHAR m_szRcx[32]; /// RDX register. TCHAR m_szRdx[32]; /// RSI register. TCHAR m_szRsi[32]; /// RDI register. TCHAR m_szRdi[32]; /// RSP register. TCHAR m_szRsp[32]; /// RBP register. TCHAR m_szRbp[32]; /// RIP register. TCHAR m_szRip[32]; /// CS register. TCHAR m_szSegCs[16]; /// DS register. TCHAR m_szSegDs[16]; /// SS register. TCHAR m_szSegSs[16]; /// ES register. TCHAR m_szSegEs[16]; /// FS register. TCHAR m_szSegFs[16]; /// GS register. TCHAR m_szSegGs[16]; /// EFLAGS register. TCHAR m_szEFlags[16]; #else #error CPU architecture is not supported. #endif }; /// Handle to the process for which symbols are to be maintained. HANDLE m_hSymProcess; /// Handle of DbgHelp.dll module. HINSTANCE m_hDbgHelpDll; /// Handle of Kernel32.dll module. HINSTANCE m_hKernelDll; /// Current exception information. PEXCEPTION_POINTERS m_pExceptionPointers; /// Date and time of the crash. SYSTEMTIME m_DateTime; /// Type of the exception. EXCEPTION_TYPE m_eExceptionType; /// Exception address corrected according to C++ exception information. DWORD64 m_dwExceptionAddress; /// Start context exception information. CONTEXT m_StartExceptionContext; /// COM error information. CInterfacePtr m_pErrorInfo; /// System error code. DWORD m_dwLastError; /// Screen shot data. CScreenShotPtr m_pScreenShot; /// Stack walk context record. CStackWalkContext m_swContext; /// Frame count (in rare cases DbgHelp could produce infinite stack traces). DWORD m_dwFrameCount; #ifdef _MANAGED /// Managed stack trace. CNetStackTrace* m_pNetStackTrace; #endif /// Pointer to SymGetOptions() function. PFSymGetOptions FSymGetOptions; /// Pointer to SymSetOptions() function. PFSymSetOptions FSymSetOptions; /// Pointer to SymInitialize() function. PFSymInitialize FSymInitialize; /// Pointer to SymCleanup() function. PFSymCleanup FSymCleanup; /// Pointer to SymGetModuleBase64() function. PFSymGetModuleBase64 FSymGetModuleBase64; /// Pointer to SymFromAddr() function. PFSymFromAddr FSymFromAddr; /// Pointer to SymGetLineFromAddr64() function. PFSymGetLineFromAddr64 FSymGetLineFromAddr64; /// Pointer to StackWalk64() function. PFStackWalk64 FStackWalk64; /// Pointer to SymFunctionTableAccess64() function. PFSymFunctionTableAccess64 FSymFunctionTableAccess64; /// Pointer to MiniDumpWriteDump() function. PFMiniDumpWriteDump FMiniDumpWriteDump; /// Pointer to OpenThread() function. PFOpenThread FOpenThread; /// Get string representation of system exception code. static PCTSTR ConvertExceptionCodeToString(DWORD dwException); /// Adapter for ReadProcessMemory() function called from StackWalk64() function. static BOOL CALLBACK ReadProcessMemoryProc64(HANDLE hProcess, DWORD64 pBaseAddress, PVOID pBuffer, DWORD dwSize, PDWORD pdwNumberOfBytesRead); /// Safely copy memory blocks. static void SafeCopy(PVOID pDestination, PVOID pSource, DWORD dwSize); /// Add new file to zip archive. static BOOL AddFileToArchive(zipFile hZipFile, PCTSTR pszFilePath, PCTSTR pszFileName); /// Adjust exception stack frame according to C++ exception. BOOL AdjustExceptionStackFrame(void); /// Inittialize stack from the thread/exception context. static void InitStackFrame(LPSTACKFRAME64 pStackFrame, const CONTEXT* pContext); /// Set stack frame structure to initial value. static BOOL GetCurrentThreadContext(PCONTEXT pContext); /// Set stack frame structure to initial value. BOOL InitStackTrace(HANDLE hThread); /// Set stack frame structure to initial value. BOOL InitStackTrace(LPSTACKFRAME64 pStackFrame); /// Get stack trace info for the interrupted thread. void GetWin32StackTrace(CUTF8EncStream& rEncStream, DWORD dwThreadID, HANDLE hThread, PCSTR pszThreadStatus); /// Get stack trace info for the interrupted thread. void GetWin32StackTrace(CXmlWriter& rXmlWriter, DWORD dwThreadID, HANDLE hThread, PCTSTR pszThreadStatus); /// Get error information in XML format. BOOL GetErrorInfo(CXmlWriter& rXmlWriter); #ifdef _MANAGED /// Get error information in XML format. BOOL GetErrorInfo(CXmlWriter& rXmlWriter, CNetStackTrace* pNetStackTrace, gcroot exception, DWORD dwNestedLevel); #endif /// Get register values. void GetRegistersInfo(CXmlWriter& rXmlWriter); /// Get system error information. void GetSysErrorInfo(CXmlWriter& rXmlWriter); /// Get COM error information. void GetComErrorInfo(CXmlWriter& rXmlWriter); /// Get description of system CPUs. void GetCpusInfo(CXmlWriter& rXmlWriter); /// Get OS information. void GetOsInfo(CXmlWriter& rXmlWriter); /// Get system memory information. void GetMemInfo(CXmlWriter& rXmlWriter); #ifdef _MANAGED /// Get stack trace info for interrupted .NET thread. void GetNetStackTrace(CUTF8EncStream& rEncStream); /// Get stack trace info for interrupted .NET thread. void GetNetStackTrace(CXmlWriter& rXmlWriter); #endif /// Get stack trace info for all threads. void GetWin32ThreadsList(CUTF8EncStream& rEncStream, CEnumProcess* pEnumProcess); /// Get stack trace info for all threads. void GetWin32ThreadsList(CXmlWriter& rXmlWriter, CEnumProcess* pEnumProcess); #ifdef _MANAGED /// Get stack trace info for all threads. void GetNetThreadsList(CUTF8EncStream& rEncStream); /// Get stack trace info for all threads. void GetNetThreadsList(CXmlWriter& rXmlWriter); #endif /// Get module list for specified process. void GetModuleList(CUTF8EncStream& rEncStream, CEnumProcess* pEnumProcess, CEnumProcess::CProcessEntry& rProcEntry); /// Get module list for specified process. void GetModuleList(CXmlWriter& rXmlWriter, CEnumProcess* pEnumProcess, CEnumProcess::CProcessEntry& rProcEntry); #ifdef _MANAGED /// Get assemblies list for current process. void GetAssemblyList(CUTF8EncStream& rEncStream); /// Get assemblies list for current process. void GetAssemblyList(CXmlWriter& rXmlWriter); #endif /// Get process info for specified process. void GetProcessList(CUTF8EncStream& rEncStream, CEnumProcess* pEnumProcess); /// Get process info for specified process. void GetProcessList(CXmlWriter& rXmlWriter, CEnumProcess* pEnumProcess); /// Get OS information. static void GetOsInfo(COsInfo& rOsInfo); /// Get description of system CPUs. static void GetCpusInfo(CCpusInfo& rCpusInfo); /// Get description of specific CPU. static BOOL GetCpuInfo(DWORD dwCpuNum, CCpuInfo& rCpuInfo); /// Get system memory information. static void GetMemInfo(CMemInfo& rMemInfo); /// Get system error information. void GetSysErrorInfo(CSysErrorInfo& rErrorInfo); /// Get COM error reason. BOOL GetComErrorInfo(CComErrorInfo& rErrorInfo); /// Get crash location and error reason. BOOL GetErrorInfo(CErrorInfo& rErrorInfo); /// Get string with CPU registers for the crash. void GetRegistersValues(CRegistersValues& rRegVals); /// Get text representation of topmost call stack entry. BOOL GetFirstWin32StackTraceString(CUTF8EncStream& rEncStream, HANDLE hThread = NULL); /// Get text representation of lower call stack entry. BOOL GetNextWin32StackTraceString(CUTF8EncStream& rEncStream); #ifdef _MANAGED /// Get text representation of topmost call stack entry. BOOL GetFirstNetStackTraceString(CUTF8EncStream& rEncStream); /// Get text representation of lower call stack entry. BOOL GetNextNetStackTraceString(CUTF8EncStream& rEncStream); #endif /// Get string with CPU registers for the crash. void GetRegistersString(CUTF8EncStream& rEncStream); /// Get crash location and reason. BOOL GetWin32ErrorString(CUTF8EncStream& rEncStream); #ifdef _MANAGED /// Get crash location and reason. BOOL GetNetErrorString(CUTF8EncStream& rEncStream); /// Get crash location and reason. BOOL GetNetErrorStringEx(CUTF8EncStream& rEncStream); #endif /// Get crash location and reason. BOOL GetErrorString(CUTF8EncStream& rEncStream); /// Get system error description. void GetSysErrorString(CUTF8EncStream& rEncStream); /// Get COM error reason. void GetComErrorString(CUTF8EncStream& rEncStream); /// Get description of system CPUs. static void GetCpuString(CUTF8EncStream& rEncStream); /// Get OS information. static void GetOsString(CUTF8EncStream& rEncStream); /// Get description of system memory. static void GetMemString(CUTF8EncStream& rEncStream); /// Get process environment strings. static void GetEnvironmentStrings(CUTF8EncStream& rEncStream); /// Get process environment strings. static void GetEnvironmentStrings(CXmlWriter& rXmlWriter); /// Get the list of computer IP addresses. static void GetComputerIPs(CStrStream& rStream); /// Get the list of computer IP addresses. static void GetComputerIPs(CUTF8EncStream& rEncStream); /// Get the list of computer IP addresses. static void GetComputerIPs(CXmlWriter& rXmlWriter); /// Get date-time string. void GetDateTime(PTSTR pszDateTime, DWORD dwDateTimeSize); /// Get time-stamp string. void GetTimeStamp(PTSTR pszTimeStamp, DWORD dwTimeStampSize); /// Generate comprehensive text information about the crash. void GetErrorLog(CUTF8EncStream& rEncStream, CEnumProcess* pEnumProcess); /// Generate comprehensive text information about the crash. void GetErrorLog(CXmlWriter& rXmlWriter, CEnumProcess* pEnumProcess); /// Protects the class from being accidentally copied. CSymEngine(const CSymEngine& rSymEngine); /// Protects the class from being accidentally copied. CSymEngine& operator=(const CSymEngine& rSymEngine); public: /// Initialize the object. explicit CSymEngine(const CEngineParams& rParams); /// Destroy the object. ~CSymEngine(void); /// Set engine parameters void SetEngineParameters(const CEngineParams& rParams); /// Reset engine parameters. void ResetEngineParameters(void); /// Returns true if DbgHelp.dll on user computer supports MiniDumpWriteDump() function. BOOL IsMiniDumpSupported(void) const; /// Writes report to file in compressed or uncompressed format. BOOL WriteReport(PCTSTR pszFileName, CEnumProcess* pEnumProcess); /// Archive report files. BOOL ArchiveReportFiles(PCTSTR pszReportFolder, PCTSTR pszArchiveFileName); /// Writes crash log and mini-dump to zip archive. BOOL WriteReportArchive(PCTSTR pszArchiveFileName, CEnumProcess* pEnumProcess); /// Append file to the report. static BOOL AppendFileToReport(PCTSTR pszArchiveFileName, PCTSTR pszFileName); /// Write report files to a folder. BOOL WriteReportFiles(PCTSTR pszFolderName, CEnumProcess* pEnumProcess); /// Writes crash log to file. BOOL WriteLog(PCTSTR pszFileName, CEnumProcess* pEnumProcess); /// Writes crash dump to file. BOOL WriteDump(PCTSTR pszFileName); /// Writes screen-shot to file. BOOL WriteScreenShot(PCTSTR pszFileName); /// Get extension of report file. static PCTSTR GetReportFileExtension(void); /// Get extension of log file. static PCTSTR GetLogFileExtension(void); /// Automatically generate log/mini-dump file name according to the date and time of the crash. void GetReportFileName(PCTSTR pszExtension, PTSTR pszFileName, DWORD dwBufferSize) const; /// Automatically generate log/mini-dump file name according to the date and time of the crash. void GetReportFileName(PTSTR pszFileName, DWORD dwBufferSize) const; /// Get structured representation of topmost call stack entry. BOOL GetFirstStackTraceEntry(CStackTraceEntry& rEntry, HANDLE hThread = NULL); /// Get structured representation of lower call stack entry. BOOL GetNextStackTraceEntry(CStackTraceEntry& rEntry); #ifdef _MANAGED /// Get structured representation of topmost call stack entry. BOOL GetFirstStackTraceEntry(CNetStackTrace::CNetStackTraceEntry& rEntry); /// Get structured representation of lower call stack entry. BOOL GetNextStackTraceEntry(CNetStackTrace::CNetStackTraceEntry& rEntry); #endif /// Get string with CPU registers for the crash. void GetRegistersString(PTSTR pszRegString, DWORD dwRegStringSize); /// Get crash location and error reason. BOOL GetWin32ErrorString(CStrStream& rStream); #ifdef _MANAGED /// Return true if .NET exception info is valid. BOOL IsNetException(void) const; /// Get crash location and error reason. BOOL GetNetErrorString(CStrStream& rStream); /// Get crash location and error reason, including inner exception info. BOOL GetNetErrorStringEx(CStrStream& rStream); #endif /// Get crash location and error reason. BOOL GetErrorString(CStrStream& rStream); /// Get description of system CPUs. static void GetCpuString(CStrStream& rStream); /// Get user-friendly module version string. static BOOL GetVersionString(PCTSTR pszModuleName, PTSTR pszVersionString, DWORD dwVersionStringSize); /// Get OS information. static void GetOsString(PTSTR pszOSString, DWORD dwOSStringSize); /// Get description of system memory. static void GetMemString(PTSTR pszMemString, DWORD dwMemStringSize); /// Get process environment strings. static void GetEnvironmentStrings(CStrStream& rStream); }; inline CSymEngine::CStackWalkContext::CStackWalkContext(void) { ZeroMemory(this, sizeof(*this)); } /** * @param hProcess - handle to the process. * @param pBaseAddress - base of memory area. * @param pBuffer - data buffer. * @param dwSize - number of bytes to read. * @param pdwNumberOfBytesRead - number of bytes read. * @return if the function succeeds, the return value is nonzero. */ inline BOOL CALLBACK CSymEngine::ReadProcessMemoryProc64(HANDLE hProcess, DWORD64 pBaseAddress, PVOID pBuffer, DWORD dwSize, PDWORD pdwNumberOfBytesRead) { hProcess; #if defined _M_IX86 return ReadProcessMemory(GetCurrentProcess(), (PVOID)pBaseAddress, pBuffer, dwSize, pdwNumberOfBytesRead); #elif defined _M_X64 size_t nNumberOfBytesRead; BOOL bResult = ReadProcessMemory(GetCurrentProcess(), (PVOID)pBaseAddress, pBuffer, dwSize, &nNumberOfBytesRead); *pdwNumberOfBytesRead = (DWORD)nNumberOfBytesRead; return bResult; #else #error CPU architecture is not supported. #endif } /** * @return true if DbgHelp.dll on client computer has MiniDumpWriteDump() function. */ inline BOOL CSymEngine::IsMiniDumpSupported(void) const { return (FMiniDumpWriteDump != NULL); } inline CSymEngine::CScreenShot::CBitmapInfo::CBitmapInfo(void) { ZeroMemory(this, sizeof(*this)); } inline CSymEngine::CScreenShot::CBitmapInfo::~CBitmapInfo(void) { Destroy(); } inline void CSymEngine::CScreenShot::CBitmapInfo::Free(void) { Destroy(); ZeroMemory(this, sizeof(*this)); } inline void CSymEngine::CScreenShot::CBitmapInfo::Destroy(void) { delete[] (PBYTE)m_pBitsArray; delete[] (PBYTE)m_pBmpInfo; } inline CSymEngine::CScreenShot::~CScreenShot(void) { delete[] m_arrBitmaps; } inline CSymEngine::CSysErrorInfo::CSysErrorInfo(void) { *m_szErrorCode = _T('\0'); m_pszMessageBuffer = NULL; } inline CSymEngine::CSysErrorInfo::~CSysErrorInfo(void) { FreeData(); } inline void CSymEngine::CSysErrorInfo::FreeData(void) { if (m_pszMessageBuffer) LocalFree(m_pszMessageBuffer); } /** * @param rErrorInfo - another error info object. */ inline CSymEngine::CSysErrorInfo::CSysErrorInfo(const CSysErrorInfo& rErrorInfo) { CopyData(rErrorInfo); } /** * @param pszFileName - buffer for resulting file name. * @param dwBufferSize - size of file name buffer. */ inline void CSymEngine::GetReportFileName(PTSTR pszFileName, DWORD dwBufferSize) const { PCTSTR pszReportExtension = GetReportFileExtension(); GetReportFileName(pszReportExtension, pszFileName, dwBufferSize); } #ifndef _MANAGED /** * @param rStream - stream object. * @return true if error info is not empty. */ inline BOOL CSymEngine::GetErrorString(CStrStream& rStream) { return GetWin32ErrorString(rStream); } /** * @param rEncStream - UTF-8 encoder object. * @return true if error info is not empty. */ inline BOOL CSymEngine::GetErrorString(CUTF8EncStream& rEncStream) { return GetWin32ErrorString(rEncStream); } #endif #ifdef _MANAGED /** * @param rEntry - stack entry information. * @return true if there is information about stack entry. */ inline BOOL CSymEngine::GetFirstStackTraceEntry(CNetStackTrace::CNetStackTraceEntry& rEntry) { _ASSERTE(m_pNetStackTrace != NULL); return (m_pNetStackTrace != NULL ? m_pNetStackTrace->GetFirstStackTraceEntry(rEntry) : FALSE); } /** * @param rEntry - stack entry information. * @return true if there is information about stack entry. */ inline BOOL CSymEngine::GetNextStackTraceEntry(CNetStackTrace::CNetStackTraceEntry& rEntry) { _ASSERTE(m_pNetStackTrace != NULL); return (m_pNetStackTrace != NULL ? m_pNetStackTrace->GetNextStackTraceEntry(rEntry) : FALSE); } /** * @param rEncStream - UTF-8 encoder object. * @return true if thread context was successfully resolved. */ inline BOOL CSymEngine::GetFirstNetStackTraceString(CUTF8EncStream& rEncStream) { _ASSERTE(m_pNetStackTrace != NULL); return (m_pNetStackTrace != NULL ? m_pNetStackTrace->GetFirstStackTraceString(rEncStream) : FALSE); } /** * @param rEncStream - UTF-8 encoder object. * @return true if thread context was successfully resolved. */ inline BOOL CSymEngine::GetNextNetStackTraceString(CUTF8EncStream& rEncStream) { _ASSERTE(m_pNetStackTrace != NULL); return (m_pNetStackTrace != NULL ? m_pNetStackTrace->GetNextStackTraceString(rEncStream) : FALSE); } /** * @param rEncStream - UTF-8 encoder object. */ inline void CSymEngine::GetNetThreadsList(CUTF8EncStream& rEncStream) { rEncStream; // TBD } /** * @param rXmlWriter - XML writer. */ inline void CSymEngine::GetNetThreadsList(CXmlWriter& rXmlWriter) { rXmlWriter; // TBD } /** * @return true if .NET exception info is valid. */ inline BOOL CSymEngine::IsNetException(void) const { return (NetThunks::IsNetException() && m_pNetStackTrace != NULL); } #endif