diff options
| author | Kargatum <dowlandtop@yandex.com> | 2021-06-25 00:50:18 +0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-24 19:50:18 +0200 |
| commit | 3c24b511f2fb2b23618e9cd0b24d28cb5afa34ad (patch) | |
| tree | 78baa1669874acf8b7adf1c1994e383e814a3146 /src/common/Debugging/WheatyExceptionReport.cpp | |
| parent | 33c271cc7c191f72406873d81abd954525d093c0 (diff) | |
refactor(Core/Misc): add braces and impove codestyle (#6402)
Diffstat (limited to 'src/common/Debugging/WheatyExceptionReport.cpp')
| -rw-r--r-- | src/common/Debugging/WheatyExceptionReport.cpp | 210 |
1 files changed, 208 insertions, 2 deletions
diff --git a/src/common/Debugging/WheatyExceptionReport.cpp b/src/common/Debugging/WheatyExceptionReport.cpp index e0fde5d53c..8618611b65 100644 --- a/src/common/Debugging/WheatyExceptionReport.cpp +++ b/src/common/Debugging/WheatyExceptionReport.cpp @@ -41,7 +41,9 @@ inline LPTSTR ErrorMessage(DWORD dw) (LPTSTR) &lpMsgBuf, 0, nullptr); if (formatResult != 0) + { return (LPTSTR)lpMsgBuf; + } else { LPTSTR msgBuf = (LPTSTR)LocalAlloc(LPTR, 30); @@ -98,9 +100,13 @@ WheatyExceptionReport::WheatyExceptionReport() // Constructor WheatyExceptionReport::~WheatyExceptionReport() { if (m_previousFilter) + { SetUnhandledExceptionFilter(m_previousFilter); + } if (m_previousCrtHandler) + { _set_invalid_parameter_handler(m_previousCrtHandler); + } ClearSymbols(); } @@ -113,18 +119,24 @@ LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter( std::unique_lock<std::mutex> guard(alreadyCrashedLock); // Handle only 1 exception in the whole process lifetime if (alreadyCrashed) + { return EXCEPTION_EXECUTE_HANDLER; + } alreadyCrashed = true; if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW) + { stackOverflowException = true; + } TCHAR module_folder_name[MAX_PATH]; GetModuleFileName(0, module_folder_name, MAX_PATH); TCHAR* pos = _tcsrchr(module_folder_name, '\\'); if (!pos) + { return 0; + } pos[0] = '\0'; ++pos; @@ -133,7 +145,9 @@ LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter( if (!CreateDirectory(crash_folder_path, nullptr)) { if (GetLastError() != ERROR_ALREADY_EXISTS) + { return 0; + } } SYSTEMTIME systime; @@ -197,9 +211,13 @@ LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter( } if (m_previousFilter) + { return m_previousFilter(pExceptionInfo); + } else + { return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/; + } } void __cdecl WheatyExceptionReport::WheatyCrtHandler(wchar_t const* /*expression*/, wchar_t const* /*function*/, wchar_t const* /*file*/, unsigned int /*line*/, uintptr_t /*pReserved*/) @@ -210,26 +228,34 @@ void __cdecl WheatyExceptionReport::WheatyCrtHandler(wchar_t const* /*expression BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxcount) { if (!sProcessorName) + { return FALSE; + } HKEY hKey; LONG lRet; lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_QUERY_VALUE, &hKey); if (lRet != ERROR_SUCCESS) + { return FALSE; + } TCHAR szTmp[2048]; DWORD cntBytes = sizeof(szTmp); lRet = ::RegQueryValueEx(hKey, _T("ProcessorNameString"), nullptr, nullptr, (LPBYTE)szTmp, &cntBytes); if (lRet != ERROR_SUCCESS) + { return FALSE; + } ::RegCloseKey(hKey); sProcessorName[0] = '\0'; // Skip spaces TCHAR* psz = szTmp; while (iswspace(*psz)) + { ++psz; + } _tcsncpy(sProcessorName, psz, maxcount); return TRUE; } @@ -257,7 +283,9 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) { osvi.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); if (!RtlGetVersion((PRTL_OSVERSIONINFOW)&osvi)) + { return FALSE; + } } *szVersion = _T('\0'); @@ -282,40 +310,68 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) if (osvi.dwMajorVersion == 10) { if (productType == VER_NT_WORKSTATION) + { _tcsncat(szVersion, _T("Windows 10 "), cntMax); + } else + { _tcsncat(szVersion, _T("Windows Server 2016 "), cntMax); + } } else if (osvi.dwMajorVersion == 6) { if (productType == VER_NT_WORKSTATION) { if (osvi.dwMinorVersion == 3) + { _tcsncat(szVersion, _T("Windows 8.1 "), cntMax); + } else if (osvi.dwMinorVersion == 2) + { _tcsncat(szVersion, _T("Windows 8 "), cntMax); + } else if (osvi.dwMinorVersion == 1) + { _tcsncat(szVersion, _T("Windows 7 "), cntMax); + } else + { _tcsncat(szVersion, _T("Windows Vista "), cntMax); + } } else if (osvi.dwMinorVersion == 3) + { _tcsncat(szVersion, _T("Windows Server 2012 R2 "), cntMax); + } else if (osvi.dwMinorVersion == 2) + { _tcsncat(szVersion, _T("Windows Server 2012 "), cntMax); + } else if (osvi.dwMinorVersion == 1) + { _tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax); + } else + { _tcsncat(szVersion, _T("Windows Server 2008 "), cntMax); + } } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + { _tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax); + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + { _tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax); + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + { _tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax); + } else if (osvi.dwMajorVersion <= 4) + { _tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax); + } // Test for specific product on Windows NT 4.0 SP6 and later. if (bVersionEx >= 0) @@ -324,13 +380,21 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) if (productType == VER_NT_WORKSTATION) { if (osvi.dwMajorVersion == 4) + { _tcsncat(szVersion, _T("Workstation 4.0 "), cntMax); + } else if (suiteMask & VER_SUITE_PERSONAL) + { _tcsncat(szVersion, _T("Home Edition "), cntMax); + } else if (suiteMask & VER_SUITE_EMBEDDEDNT) + { _tcsncat(szVersion, _T("Embedded "), cntMax); + } else + { _tcsncat(szVersion, _T("Professional "), cntMax); + } } // Test for the server type. else if (productType == VER_NT_SERVER) @@ -338,40 +402,66 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) if (osvi.dwMajorVersion == 6 || osvi.dwMajorVersion == 10) { if (suiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED) + { _tcsncat(szVersion, _T("Essentials "), cntMax); + } else if (suiteMask & VER_SUITE_DATACENTER) + { _tcsncat(szVersion, _T("Datacenter "), cntMax); + } else if (suiteMask & VER_SUITE_ENTERPRISE) + { _tcsncat(szVersion, _T("Enterprise "), cntMax); + } else + { _tcsncat(szVersion, _T("Standard "), cntMax); + } } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { if (suiteMask & VER_SUITE_DATACENTER) + { _tcsncat(szVersion, _T("Datacenter Edition "), cntMax); + } else if (suiteMask & VER_SUITE_ENTERPRISE) + { _tcsncat(szVersion, _T("Enterprise Edition "), cntMax); + } else if (suiteMask == VER_SUITE_BLADE) + { _tcsncat(szVersion, _T("Web Edition "), cntMax); + } else + { _tcsncat(szVersion, _T("Standard Edition "), cntMax); + } } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { if (suiteMask & VER_SUITE_DATACENTER) + { _tcsncat(szVersion, _T("Datacenter Server "), cntMax); + } else if (suiteMask & VER_SUITE_ENTERPRISE) + { _tcsncat(szVersion, _T("Advanced Server "), cntMax); + } else + { _tcsncat(szVersion, _T("Server "), cntMax); + } } else // Windows NT 4.0 { if (suiteMask & VER_SUITE_ENTERPRISE) + { _tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax); + } else + { _tcsncat(szVersion, _T("Server 4.0 "), cntMax); + } } } } @@ -438,9 +528,13 @@ void WheatyExceptionReport::PrintSystemInfo() SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys / 0x400, MemoryStatus.dwAvailPhys / 0x400, MemoryStatus.dwTotalPageFile / 0x400); if (_GetWindowsVersion(sString, countof(sString))) + { Log(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString); + } else + { Log(_T("\r\n*** Operation System:\r\n<unknown>\r\n")); + } } //=========================================================================== @@ -453,7 +547,9 @@ void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables) // Take a snapshot of all running threads HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hThreadSnap == INVALID_HANDLE_VALUE) + { return; + } // Fill in the size of the structure before using it. te32.dwSize = sizeof(THREADENTRY32); @@ -480,7 +576,9 @@ void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables) if (threadHandle) { if (GetThreadContext(threadHandle, &context)) + { WriteStackDetails(&context, bWriteVariables, threadHandle); + } CloseHandle(threadHandle); } } @@ -663,15 +761,21 @@ BOOL WheatyExceptionReport::GetLogicalAddress( MEMORY_BASIC_INFORMATION mbi; if (!VirtualQuery(addr, &mbi, sizeof(mbi))) + { return FALSE; + } DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase; if (!hMod) + { return FALSE; + } if (!GetModuleFileName((HMODULE)hMod, szModule, len)) + { return FALSE; + } // Point to the DOS header in memory PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod; @@ -771,9 +875,13 @@ void WheatyExceptionReport::WriteStackDetails( SymFunctionTableAccess64, SymGetModuleBase64, 0)) + { break; + } if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure - break; // the frame is OK. Bail if not. + { + break; // the frame is OK. Bail if not. + } #ifdef _M_IX86 Log(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset); #endif @@ -870,7 +978,9 @@ bool WheatyExceptionReport::FormatSymbolValue( { // If it's a function, don't do anything. if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK + { return false; + } DWORD_PTR pVariable = 0; // Will point to the variable's data in memory @@ -890,7 +1000,9 @@ bool WheatyExceptionReport::FormatSymbolValue( // return false; } else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER) - return false; // Don't try to report register variable + { + return false; // Don't try to report register variable + } else { pVariable = (DWORD_PTR)pSym->Address; // It must be a global variable @@ -900,9 +1012,13 @@ bool WheatyExceptionReport::FormatSymbolValue( // Indicate if the variable is a local or parameter if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER) + { symbolDetails.top().Prefix = "Parameter "; + } else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL) + { symbolDetails.top().Prefix = "Local "; + } // Determine if the variable is a user defined type (UDT). IF so, bHandled // will return true. @@ -916,11 +1032,15 @@ bool WheatyExceptionReport::FormatSymbolValue( // DWORD. BasicType basicType = GetBasicType(pSym->TypeIndex, pSym->ModBase); if (symbolDetails.top().Type.empty()) + { symbolDetails.top().Type = rgBaseType[basicType]; + } // Emit the variable name if (pSym->Name[0] != '\0') + { symbolDetails.top().Name = pSym->Name; + } char buffer[50]; FormatOutputValue(buffer, basicType, pSym->Size, (PVOID)pVariable, sizeof(buffer)); @@ -949,11 +1069,15 @@ void WheatyExceptionReport::DumpTypeIndex( bHandled = false; if (newSymbol) + { PushSymbolDetail(); + } DWORD typeTag; if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag)) + { return; + } // Get the name of the symbol. This will either be a Type name (if a UDT), // or the structure member name. @@ -970,7 +1094,9 @@ void WheatyExceptionReport::DumpTypeIndex( FormatOutputValue(buffer, btStdString, 0, (PVOID)offset, sizeof(buffer)); symbolDetails.top().Value = buffer; if (Name != nullptr && Name[0] != '\0') + { symbolDetails.top().Name = Name; + } bHandled = true; return; } @@ -984,18 +1110,24 @@ void WheatyExceptionReport::DumpTypeIndex( symbolDetails.top().Name = Name; } else if (buffer[0] != '\0') + { symbolDetails.top().Name = buffer; + } LocalFree(pwszTypeName); } else if (Name != nullptr && Name[0] != '\0') + { symbolDetails.top().Name = Name; + } if (!StoreSymbol(dwTypeIndex, offset)) { // Skip printing address and base class if it has been printed already if (typeTag == SymTagBaseClass) + { bHandled = true; + } return; } @@ -1006,7 +1138,9 @@ void WheatyExceptionReport::DumpTypeIndex( if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID)) { if (Name != nullptr && Name[0] != '\0') + { symbolDetails.top().Name = Name; + } BOOL isReference; SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference); @@ -1015,9 +1149,13 @@ void WheatyExceptionReport::DumpTypeIndex( memset(addressStr, 0, sizeof(addressStr)); if (isReference) + { symbolDetails.top().Suffix += "&"; + } else + { symbolDetails.top().Suffix += "*"; + } // Try to dereference the pointer in a try/except block since it might be invalid DWORD_PTR address = DereferenceUnsafePointer(offset); @@ -1027,11 +1165,15 @@ void WheatyExceptionReport::DumpTypeIndex( symbolDetails.top().Value = buffer; if (symbolDetails.size() >= WER_MAX_NESTING_LEVEL) + { logChildren = false; + } // no need to log any children since the address is invalid anyway if (address == NULL || address == DWORD_PTR(-1)) + { logChildren = false; + } DumpTypeIndex(modBase, innerTypeID, address, bHandled, Name, addressStr, false, logChildren); @@ -1039,12 +1181,18 @@ void WheatyExceptionReport::DumpTypeIndex( { BasicType basicType = GetBasicType(dwTypeIndex, modBase); if (symbolDetails.top().Type.empty()) + { symbolDetails.top().Type = rgBaseType[basicType]; + } if (address == NULL) + { symbolDetails.top().Value = "NULL"; + } else if (address == DWORD_PTR(-1)) + { symbolDetails.top().Value = "<Unable to read memory>"; + } else { // Get the size of the child member @@ -1058,7 +1206,9 @@ void WheatyExceptionReport::DumpTypeIndex( return; } else if (address == NULL) + { symbolDetails.top().Value = "NULL"; + } else if (address == DWORD_PTR(-1)) { symbolDetails.top().Value = "<Unable to read memory>"; @@ -1072,19 +1222,25 @@ void WheatyExceptionReport::DumpTypeIndex( { DWORD innerTypeTag; if (!SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMTAG, &innerTypeTag)) + { break; + } switch (innerTypeTag) { case SymTagUDT: if (symbolDetails.size() >= WER_MAX_NESTING_LEVEL) + { logChildren = false; + } DumpTypeIndex(modBase, innerTypeID, offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren); break; case SymTagPointerType: if (Name != nullptr && Name[0] != '\0') + { symbolDetails.top().Name = Name; + } DumpTypeIndex(modBase, innerTypeID, offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren); break; @@ -1112,15 +1268,21 @@ void WheatyExceptionReport::DumpTypeIndex( DWORD elementsCount; if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_COUNT, &elementsCount)) + { symbolDetails.top().Suffix += "[" + std::to_string(elementsCount) + "]"; + } else + { symbolDetails.top().Suffix += "[<unknown count>]"; + } if (!bHandled) { basicType = GetBasicType(dwTypeIndex, modBase); if (symbolDetails.top().Type.empty()) + { symbolDetails.top().Type = rgBaseType[basicType]; + } bHandled = true; } @@ -1184,7 +1346,9 @@ void WheatyExceptionReport::DumpTypeIndex( SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount); if (!dwChildrenCount) // If no children, we're done + { return; + } // Prepare to get an array of "TypeIds", representing each of the children. // SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a @@ -1215,7 +1379,9 @@ void WheatyExceptionReport::DumpTypeIndex( symTag == SymTagEnum || symTag == SymTagTypedef || symTag == SymTagVTable) + { continue; + } // Ignore static fields DWORD dataKind; @@ -1223,7 +1389,9 @@ void WheatyExceptionReport::DumpTypeIndex( if (dataKind == DataIsStaticLocal || dataKind == DataIsGlobal || dataKind == DataIsStaticMember) + { continue; + } symbolDetails.top().HasChildren = true; if (!logChildren) @@ -1252,7 +1420,9 @@ void WheatyExceptionReport::DumpTypeIndex( if (!bHandled2) { if (symbolDetails.top().Type.empty()) + { symbolDetails.top().Type = rgBaseType[basicType]; + } // Get the real "TypeId" of the child. We need this for the // SymGetTypeInfo(TI_GET_TYPEID) call below. @@ -1291,36 +1461,56 @@ void WheatyExceptionReport::FormatOutputValue(char* pszCurrBuffer, { // Special case handling for char[] type if (countOverride != 0) + { length = countOverride; + } else + { length = strlen((char*)pAddress); + } if (length > bufferSize - 6) + { pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress); + } else + { pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress); + } break; } case btStdString: { std::string* value = static_cast<std::string*>(pAddress); if (value->length() > bufferSize - 6) + { pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str()); + } else + { pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str()); + } break; } default: // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) if (length == 1) + { pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PBYTE)pAddress); + } else if (length == 2) + { pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PWORD)pAddress); + } else if (length == 4) { if (basicType == btFloat) + { pszCurrBuffer += sprintf(pszCurrBuffer, "%f", *(PFLOAT)pAddress); + } else + { pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PDWORD)pAddress); + } } else if (length == 8) { @@ -1401,9 +1591,13 @@ int __cdecl WheatyExceptionReport::Log(const TCHAR* format, ...) va_start(argptr, format); if (stackOverflowException) + { retValue = HeapLog(format, argptr); + } else + { retValue = StackLog(format, argptr); + } va_end(argptr); @@ -1446,7 +1640,9 @@ void WheatyExceptionReport::ClearSymbols() { symbols.clear(); while (!symbolDetails.empty()) + { symbolDetails.pop(); + } } void WheatyExceptionReport::PushSymbolDetail() @@ -1465,15 +1661,21 @@ void WheatyExceptionReport::PopSymbolDetail() void WheatyExceptionReport::PrintSymbolDetail() { if (symbolDetails.empty()) + { return; + } // Don't log anything if has been logged already or if it's empty if (symbolDetails.top().Logged || symbolDetails.top().empty()) + { return; + } // Add appropriate indentation level (since this routine is recursive) for (size_t i = 0; i < symbolDetails.size(); i++) + { Log(_T("\t")); + } Log(_T("%s\r\n"), symbolDetails.top().ToString().c_str()); @@ -1487,13 +1689,17 @@ std::string SymbolDetail::ToString() if (!Name.empty()) { if (!formatted.empty()) + { formatted += " "; + } formatted += Name; } if (!Value.empty()) { if (Name == "passwd" || Name == "password") + { Value = "<sensitive data>"; + } formatted += " = " + Value; } return formatted; |
