8#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
9#define WIN32_LEAN_AND_MEAN
10#pragma warning(disable:4996)
11#pragma warning(disable:4312)
12#pragma warning(disable:4311)
26#define CrashFolder _T("Crashes")
27#pragma comment(linker, "/DEFAULTLIB:dbghelp.lib")
29inline LPTSTR ErrorMessage(DWORD dw)
33 FORMAT_MESSAGE_ALLOCATE_BUFFER |
34 FORMAT_MESSAGE_FROM_SYSTEM,
37 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
40 return (LPTSTR)lpMsgBuf;
80 PEXCEPTION_POINTERS pExceptionInfo)
82 TCHAR module_folder_name[MAX_PATH];
83 GetModuleFileName(0, module_folder_name, MAX_PATH);
84 TCHAR* pos = _tcsrchr(module_folder_name,
'\\');
90 TCHAR crash_folder_path[MAX_PATH];
91 snprintf(crash_folder_path,
sizeof(crash_folder_path),
"%s\\%s", module_folder_name, CrashFolder);
92 if (!CreateDirectory(crash_folder_path, NULL))
94 if (GetLastError() != ERROR_ALREADY_EXISTS)
99 GetLocalTime(&systime);
101 crash_folder_path, _HASH, pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
104 crash_folder_path, _HASH, pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
111 FILE_FLAG_WRITE_THROUGH,
119 FILE_FLAG_WRITE_THROUGH,
124 MINIDUMP_EXCEPTION_INFORMATION info;
125 info.ClientPointers = FALSE;
126 info.ExceptionPointers = pExceptionInfo;
127 info.ThreadId = GetCurrentThreadId();
129 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
130 m_hDumpFile, MiniDumpWithIndirectlyReferencedMemory, &info, 0, 0);
148 return EXCEPTION_EXECUTE_HANDLER;
158 lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
159 0, KEY_QUERY_VALUE, &hKey);
160 if (lRet != ERROR_SUCCESS)
163 DWORD cntBytes =
sizeof(szTmp);
164 lRet = ::RegQueryValueEx(hKey, _T(
"ProcessorNameString"), NULL, NULL,
165 (LPBYTE)szTmp, &cntBytes);
166 if (lRet != ERROR_SUCCESS)
169 sProcessorName[0] =
'\0';
172 while (iswspace(*psz))
174 _tcsncpy(sProcessorName, psz, maxcount);
182 OSVERSIONINFOEX osvi = { 0 };
183 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEX);
184 BOOL bOsVersionInfoEx;
185 bOsVersionInfoEx = ::GetVersionEx((LPOSVERSIONINFO)(&osvi));
186 if (!bOsVersionInfoEx)
188 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
189 if (!::GetVersionEx((OSVERSIONINFO*)&osvi))
192 *szVersion = _T(
'\0');
194 switch (osvi.dwPlatformId)
197 case VER_PLATFORM_WIN32_NT:
200 BYTE suiteMask = osvi.wReserved[0];
201 BYTE productType = osvi.wReserved[1];
203 WORD suiteMask = osvi.wSuiteMask;
204 BYTE productType = osvi.wProductType;
208 if (osvi.dwMajorVersion == 10)
210 _tcsncat(szVersion, _T(
"Windows 10.0 "), cntMax);
213 else if (osvi.dwMajorVersion == 6)
215 if (productType == VER_NT_WORKSTATION)
217 if (osvi.dwMinorVersion == 3)
218 _tcsncat(szVersion, _T(
"Windows 8.1 "), cntMax);
219 if (osvi.dwMinorVersion == 2)
220 _tcsncat(szVersion, _T(
"Windows 8 "), cntMax);
221 else if (osvi.dwMinorVersion == 1)
222 _tcsncat(szVersion, _T(
"Windows 7 "), cntMax);
224 _tcsncat(szVersion, _T(
"Windows Vista "), cntMax);
226 else if (osvi.dwMinorVersion == 3)
227 _tcsncat(szVersion, _T(
"Windows Server 2012 R2 "), cntMax);
228 else if (osvi.dwMinorVersion == 2)
229 _tcsncat(szVersion, _T(
"Windows Server 2012 "), cntMax);
230 else if (osvi.dwMinorVersion == 1)
231 _tcsncat(szVersion, _T(
"Windows Server 2008 R2 "), cntMax);
233 _tcsncat(szVersion, _T(
"Windows Server 2008 "), cntMax);
235 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
236 _tcsncat(szVersion, _T(
"Microsoft Windows Server 2003 "), cntMax);
237 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
238 _tcsncat(szVersion, _T(
"Microsoft Windows XP "), cntMax);
239 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
240 _tcsncat(szVersion, _T(
"Microsoft Windows 2000 "), cntMax);
241 else if (osvi.dwMajorVersion <= 4)
242 _tcsncat(szVersion, _T(
"Microsoft Windows NT "), cntMax);
245 if (bOsVersionInfoEx)
248 if (productType == VER_NT_WORKSTATION)
250 if (osvi.dwMajorVersion == 4)
251 _tcsncat(szVersion, _T(
"Workstation 4.0 "), cntMax);
252 else if (suiteMask & VER_SUITE_PERSONAL)
253 _tcsncat(szVersion, _T(
"Home Edition "), cntMax);
254 else if (suiteMask & VER_SUITE_EMBEDDEDNT)
255 _tcsncat(szVersion, _T(
"Embedded "), cntMax);
257 _tcsncat(szVersion, _T(
"Professional "), cntMax);
260 else if (productType == VER_NT_SERVER)
263 if (osvi.dwMajorVersion == 6 && (osvi.dwMinorVersion == 2 || osvi.dwMinorVersion == 3))
265 if (suiteMask & VER_SUITE_DATACENTER)
266 _tcsncat(szVersion, _T(
"Datacenter Edition "), cntMax);
268 _tcsncat(szVersion, _T(
"Standard Edition "), cntMax);
271 else if (osvi.dwMajorVersion == 6 && (osvi.dwMinorVersion == 0 || osvi.dwMinorVersion == 1))
273 if (suiteMask & VER_SUITE_STORAGE_SERVER)
274 _tcsncat(szVersion, _T(
"Storage Server Edition "), cntMax);
275 else if (suiteMask & VER_SUITE_ENTERPRISE)
276 _tcsncat(szVersion, _T(
"Enterprise Edition "), cntMax);
277 else if (suiteMask & VER_SUITE_DATACENTER)
278 _tcsncat(szVersion, _T(
"Datacenter Edition "), cntMax);
279 else if (suiteMask == VER_SUITE_BLADE)
280 _tcsncat(szVersion, _T(
"Web Edition "), cntMax);
282 _tcsncat(szVersion, _T(
"Standard Edition "), cntMax);
285 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
287 if (suiteMask & VER_SUITE_STORAGE_SERVER)
288 _tcsncat(szVersion, _T(
"Storage Server Edition "), cntMax);
289 else if (suiteMask & VER_SUITE_DATACENTER)
290 _tcsncat(szVersion, _T(
"Datacenter Edition "), cntMax);
291 else if (suiteMask & VER_SUITE_ENTERPRISE)
292 _tcsncat(szVersion, _T(
"Enterprise Edition "), cntMax);
293 else if (suiteMask == VER_SUITE_BLADE)
294 _tcsncat(szVersion, _T(
"Web Edition "), cntMax);
296 _tcsncat(szVersion, _T(
"Standard Edition "), cntMax);
298 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
300 if (suiteMask & VER_SUITE_DATACENTER)
301 _tcsncat(szVersion, _T(
"Datacenter Server "), cntMax);
302 else if (suiteMask & VER_SUITE_ENTERPRISE)
303 _tcsncat(szVersion, _T(
"Advanced Server "), cntMax);
305 _tcsncat(szVersion, _T(
"Server "), cntMax);
309 if (suiteMask & VER_SUITE_ENTERPRISE)
310 _tcsncat(szVersion, _T(
"Server 4.0, Enterprise Edition "), cntMax);
312 _tcsncat(szVersion, _T(
"Server 4.0 "), cntMax);
318 if (osvi.dwMajorVersion == 4 && _tcsicmp(osvi.szCSDVersion, _T(
"Service Pack 6")) == 0)
324 lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey);
325 if (lRet == ERROR_SUCCESS)
327 _stprintf(wszTmp, _T(
"Service Pack 6a (Version %d.%d, Build %d)"),
328 osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
329 _tcsncat(szVersion, wszTmp, cntMax);
333 _stprintf(wszTmp, _T(
"%s (Version %d.%d, Build %d)"),
334 osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
335 _tcsncat(szVersion, wszTmp, cntMax);
341 if (!_tcslen(osvi.szCSDVersion))
342 _stprintf(wszTmp, _T(
"(Version %d.%d, Build %d)"),
343 osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
345 _stprintf(wszTmp, _T(
"%s (Version %d.%d, Build %d)"),
346 osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
347 _tcsncat(szVersion, wszTmp, cntMax);
352 _stprintf(wszTmp, _T(
"%s (Version %d.%d, Build %d)"),
353 osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
354 _tcsncat(szVersion, wszTmp, cntMax);
363 SYSTEM_INFO SystemInfo;
364 ::GetSystemInfo(&SystemInfo);
366 MEMORYSTATUS MemoryStatus;
367 MemoryStatus.dwLength =
sizeof(MEMORYSTATUS);
368 ::GlobalMemoryStatus(&MemoryStatus);
370 _tprintf(_T(
"//=====================================================\r\n"));
372 _tprintf(_T(
"*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
373 sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys / 0x400, MemoryStatus.dwAvailPhys / 0x400, MemoryStatus.dwTotalPageFile / 0x400);
375 _tprintf(_T(
"*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
376 SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys / 0x400, MemoryStatus.dwAvailPhys / 0x400, MemoryStatus.dwTotalPageFile / 0x400);
379 _tprintf(_T(
"\r\n*** Operation System ***\r\n%s\r\n"), sString);
381 _tprintf(_T(
"\r\n*** Operation System:\r\n<unknown>\r\n"));
389 DWORD dwOwnerPID = GetCurrentProcessId();
392 HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
393 if (hThreadSnap == INVALID_HANDLE_VALUE)
397 te32.dwSize =
sizeof(THREADENTRY32);
401 if (!Thread32First(hThreadSnap, &te32))
403 CloseHandle(hThreadSnap);
413 if (te32.th32OwnerProcessID == dwOwnerPID)
416 context.ContextFlags = 0xffffffff;
417 HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
false, te32.th32ThreadID);
420 if (GetThreadContext(threadHandle, &context))
422 CloseHandle(threadHandle);
425 }
while (Thread32Next(hThreadSnap, &te32));
428 CloseHandle(hThreadSnap);
436 PEXCEPTION_POINTERS pExceptionInfo)
439 GetLocalTime(&systime);
442 _tprintf(_T(
"Revision: %s\r\n"), SKYFIRE_VER_PRODUCTVERSION_STR);
443 _tprintf(_T(
"Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute);
444 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
448 _tprintf(_T(
"\r\n//=====================================================\r\n"));
449 _tprintf(_T(
"Exception code: %08X %s\r\n"),
450 pExceptionRecord->ExceptionCode,
454 TCHAR szFaultingModule[MAX_PATH];
459 sizeof(szFaultingModule),
463 _tprintf(_T(
"Fault address: %08X %02X:%08X %s\r\n"),
464 pExceptionRecord->ExceptionAddress,
465 section, offset, szFaultingModule);
468 _tprintf(_T(
"Fault address: %016I64X %02X:%016I64X %s\r\n"),
469 pExceptionRecord->ExceptionAddress,
470 section, offset, szFaultingModule);
473 PCONTEXT pCtx = pExceptionInfo->ContextRecord;
479 _tprintf(_T(
"EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n"),
480 pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx,
481 pCtx->Esi, pCtx->Edi);
483 _tprintf(_T(
"CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip);
484 _tprintf(_T(
"SS:ESP:%04X:%08X EBP:%08X\r\n"),
485 pCtx->SegSs, pCtx->Esp, pCtx->Ebp);
486 _tprintf(_T(
"DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
487 pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
488 _tprintf(_T(
"Flags:%08X\r\n"), pCtx->EFlags);
493 _tprintf(_T(
"RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n")
494 _T(
"R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n"),
495 pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx,
496 pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15);
497 _tprintf(_T(
"CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip);
498 _tprintf(_T(
"SS:RSP:%04X:%016X RBP:%08X\r\n"),
499 pCtx->SegSs, pCtx->Rsp, pCtx->Rbp);
500 _tprintf(_T(
"DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
501 pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
502 _tprintf(_T(
"Flags:%08X\r\n"), pCtx->EFlags);
505 SymSetOptions(SYMOPT_DEFERRED_LOADS);
508 if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
510 _tprintf(_T(
"\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"),
511 ErrorMessage(GetLastError()));
514 CONTEXT trashableContext = *pCtx;
521 _tprintf(_T(
"========================\r\n"));
522 _tprintf(_T(
"Local Variables And Parameters\r\n"));
524 trashableContext = *pCtx;
527 _tprintf(_T(
"========================\r\n"));
528 _tprintf(_T(
"Global Variables\r\n"));
530 SymEnumSymbols(GetCurrentProcess(),
531 (UINT_PTR)GetModuleHandle(szFaultingModule),
535 SymCleanup(GetCurrentProcess());
546#define EXCEPTION(x) case EXCEPTION_##x: return (LPTSTR)_T(#x);
550 EXCEPTION(ACCESS_VIOLATION)
551 EXCEPTION(DATATYPE_MISALIGNMENT)
552 EXCEPTION(BREAKPOINT)
553 EXCEPTION(SINGLE_STEP)
554 EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
555 EXCEPTION(FLT_DENORMAL_OPERAND)
556 EXCEPTION(FLT_DIVIDE_BY_ZERO)
557 EXCEPTION(FLT_INEXACT_RESULT)
558 EXCEPTION(FLT_INVALID_OPERATION)
559 EXCEPTION(FLT_OVERFLOW)
560 EXCEPTION(FLT_STACK_CHECK)
561 EXCEPTION(FLT_UNDERFLOW)
562 EXCEPTION(INT_DIVIDE_BY_ZERO)
563 EXCEPTION(INT_OVERFLOW)
564 EXCEPTION(PRIV_INSTRUCTION)
565 EXCEPTION(IN_PAGE_ERROR)
566 EXCEPTION(ILLEGAL_INSTRUCTION)
567 EXCEPTION(NONCONTINUABLE_EXCEPTION)
568 EXCEPTION(STACK_OVERFLOW)
569 EXCEPTION(INVALID_DISPOSITION)
570 EXCEPTION(GUARD_PAGE)
571 EXCEPTION(INVALID_HANDLE)
577 static TCHAR szBuffer[512] = { 0 };
579 FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
580 GetModuleHandle(_T(
"NTDLL.DLL")),
581 dwCode, 0, szBuffer,
sizeof(szBuffer), 0);
594 PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
596 MEMORY_BASIC_INFORMATION mbi;
598 if (!VirtualQuery(addr, &mbi,
sizeof(mbi)))
601 DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase;
603 if (!GetModuleFileName((HMODULE)hMod, szModule, len))
607 PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
610 PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + DWORD_PTR(pDosHdr->e_lfanew));
612 PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr);
614 DWORD_PTR rva = (DWORD_PTR)addr - hMod;
619 i < pNtHdr->FileHeader.NumberOfSections;
622 DWORD_PTR sectionStart = pSection->VirtualAddress;
623 DWORD_PTR sectionEnd = sectionStart
624 + DWORD_PTR(std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize));
627 if ((rva >= sectionStart) && (rva <= sectionEnd))
633 offset = rva - sectionStart;
643struct CSymbolInfoPackage :
public SYMBOL_INFO_PACKAGE
647 si.SizeOfStruct =
sizeof(SYMBOL_INFO);
648 si.MaxNameLen =
sizeof(name);
657 bool bWriteVariables, HANDLE pThreadHandle)
659 _tprintf(_T(
"\r\nCall stack:\r\n"));
661 _tprintf(_T(
"Address Frame Function SourceFile\r\n"));
663 DWORD dwMachineType = 0;
667 memset(&sf, 0,
sizeof(sf));
672 sf.AddrPC.Offset = pContext->Eip;
673 sf.AddrPC.Mode = AddrModeFlat;
674 sf.AddrStack.Offset = pContext->Esp;
675 sf.AddrStack.Mode = AddrModeFlat;
676 sf.AddrFrame.Offset = pContext->Ebp;
677 sf.AddrFrame.Mode = AddrModeFlat;
679 dwMachineType = IMAGE_FILE_MACHINE_I386;
683 sf.AddrPC.Offset = pContext->Rip;
684 sf.AddrPC.Mode = AddrModeFlat;
685 sf.AddrStack.Offset = pContext->Rsp;
686 sf.AddrStack.Mode = AddrModeFlat;
687 sf.AddrFrame.Offset = pContext->Rbp;
688 sf.AddrFrame.Mode = AddrModeFlat;
689 dwMachineType = IMAGE_FILE_MACHINE_AMD64;
695 if (!StackWalk64(dwMachineType,
697 pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
701 SymFunctionTableAccess64,
705 if (0 == sf.AddrFrame.Offset)
708 _tprintf(_T(
"%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
711 _tprintf(_T(
"%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
714 DWORD64 symDisplacement = 0;
718 CSymbolInfoPackage sip;
725 _tprintf(_T(
"%hs+%I64X"), sip.si.Name, symDisplacement);
729 TCHAR szModule[MAX_PATH] = _T(
"");
731 DWORD_PTR offset = 0;
734 szModule,
sizeof(szModule), section, offset);
736 _tprintf(_T(
"%04X:%08X %s"), section, offset, szModule);
739 _tprintf(_T(
"%04X:%016I64X %s"), section, offset, szModule);
744 IMAGEHLP_LINE64 lineInfo = {
sizeof(IMAGEHLP_LINE) };
745 DWORD dwLineDisplacement;
746 if (SymGetLineFromAddr64(
m_hProcess, sf.AddrPC.Offset,
747 &dwLineDisplacement, &lineInfo))
749 _tprintf(_T(
" %s line %u"), lineInfo.FileName, lineInfo.LineNumber);
758 IMAGEHLP_STACK_FRAME imagehlpStackFrame;
759 imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
760 SymSetContext(
m_hProcess, &imagehlpStackFrame, 0);
776 PSYMBOL_INFO pSymInfo,
785 szBuffer,
sizeof(szBuffer)))
790 _tprintf(_T(
"punting on symbol %s\r\n"), pSymInfo->Name);
807 char* pszCurrBuffer = pszBuffer;
810 if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER)
811 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszBuffer),
"Parameter ");
812 else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL)
813 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszBuffer),
"Local ");
819 DWORD_PTR pVariable = 0;
821 if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
825 pVariable = sf->AddrFrame.Offset;
826 pVariable += (DWORD_PTR)pSym->Address;
831 else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER)
837 pVariable = (DWORD_PTR)pSym->Address;
843 pszCurrBuffer =
DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex,
844 0, pVariable, bHandled, pSym->Name);
852 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszBuffer),
rgBaseType[basicType]);
855 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszBuffer),
"\'%s\'", pSym->Name);
873 unsigned nestingLevel,
883 if (SymGetTypeInfo(
m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
886 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" %ls", pwszTypeName);
887 LocalFree(pwszTypeName);
891 DWORD dwChildrenCount = 0;
892 SymGetTypeInfo(
m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT,
895 if (!dwChildrenCount)
896 return pszCurrBuffer;
901 struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS
903 ULONG MoreChildIds[1024];
904 FINDCHILDREN() {
Count =
sizeof(MoreChildIds) /
sizeof(MoreChildIds[0]); }
907 children.Count = dwChildrenCount;
911 if (!SymGetTypeInfo(
m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
914 return pszCurrBuffer;
918 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
"\r\n");
921 for (
unsigned i = 0; i < dwChildrenCount; i++)
924 for (
unsigned j = 0; j <= nestingLevel + 1; j++)
925 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
"\t");
930 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
rgBaseType[basicType]);
933 children.ChildId[i], nestingLevel + 1,
934 offset, bHandled2, Name);
940 DWORD dwMemberOffset;
941 SymGetTypeInfo(
m_hProcess, modBase, children.ChildId[i],
942 TI_GET_OFFSET, &dwMemberOffset);
947 SymGetTypeInfo(
m_hProcess, modBase, children.ChildId[i],
948 TI_GET_TYPEID, &typeId);
952 SymGetTypeInfo(
m_hProcess, modBase, typeId, TI_GET_LENGTH, &length);
955 DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
965 length, (PVOID)dwFinalOffset);
967 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
"\r\n");
972 return pszCurrBuffer;
982 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %X", *(PBYTE)pAddress);
983 else if (length == 2)
984 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %X", *(PWORD)pAddress);
985 else if (length == 4)
989 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %f", *(PFLOAT)pAddress);
991 else if (basicType ==
btChar)
993 if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
995 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = \"%.31s\"",
999 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %X",
1003 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %X", *(PDWORD)pAddress);
1005 else if (length == 8)
1009 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %lf",
1010 *(
double*)pAddress);
1013 pszCurrBuffer += snprintf(pszCurrBuffer,
sizeof(pszCurrBuffer),
" = %I64X",
1014 *(DWORD64*)pAddress);
1017 return pszCurrBuffer;
1024 if (SymGetTypeInfo(
m_hProcess, modBase, typeIndex,
1025 TI_GET_BASETYPE, &basicType))
1033 if (SymGetTypeInfo(
m_hProcess, modBase, typeIndex, TI_GET_TYPEID, &typeId))
1035 if (SymGetTypeInfo(
m_hProcess, modBase, typeId, TI_GET_BASETYPE,
1056 va_start(argptr, format);
1057 retValue = vsprintf(szBuff, format, argptr);
1060 WriteFile(
m_hReportFile, szBuff, retValue *
sizeof(TCHAR), &cbWritten, 0);
WheatyExceptionReport g_WheatyExceptionReport
const char *const rgBaseType[]
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle)
static TCHAR m_szLogFileName[MAX_PATH]
static HANDLE m_hReportFile
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase)
static int __cdecl _tprintf(const TCHAR *format,...)
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, DWORD §ion, DWORD_PTR &offset)
static void PrintSystemInfo()
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID)
static TCHAR m_szDumpFileName[MAX_PATH]
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter
static BOOL _GetWindowsVersion(TCHAR *szVersion, DWORD cntMax)
static LONG WINAPI WheatyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
static LPTSTR GetExceptionString(DWORD dwCode)
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo)
static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, char *)
static HANDLE m_hDumpFile
static char * FormatOutputValue(char *pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress)
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, char *pszBuffer, unsigned cbBuffer)
static BOOL _GetProcessorName(TCHAR *sProcessorName, DWORD maxcount)
static void printTracesForAllThreads()
size_t Count(const ContainerMapList< SPECIFIC_TYPE > &elements, SPECIFIC_TYPE *)