//-- static bool WriteMiniDump(EXCEPTION_POINTERS *ExceptionPointers) { HINSTANCE hDbgHelp = ::LoadLibrary(_T("dbghelp.dll")); if (hDbgHelp == NULL) return false; pfnMiniDumpWriteDump = (fnMiniDumpWriteDump)::GetProcAddress (hDbgHelp, "MiniDumpWriteDump"); if (pfnMiniDumpWriteDump == NULL) { ::FreeLibrary(hDbgHelp); return false; } TCHAR TinyPath[MAX_PATH], MiniPath[MAX_PATH], FullPath[MAX_PATH]; MakeSpecialName(TinyPath, MAX_PATH, g_suffix, _T("tiny.dmp")); MakeSpecialName(MiniPath, MAX_PATH, g_suffix, _T("mini.dmp")); MakeSpecialName(FullPath, MAX_PATH, g_suffix, _T("full.dmp")); bool tiny = WriteMiniDump(ExceptionPointers, TinyPath, MiniDumpNormal); bool mini = WriteMiniDump(ExceptionPointers, MiniPath, MiniDumpWithDataSegs); bool full = WriteMiniDump(ExceptionPointers, FullPath, MiniDumpWithFullMemory); ::FreeLibrary (hDbgHelp); return tiny || mini || full; }
//----------------------------------------------------------------------------- // Purpose: Destructor. Deletes all children. //----------------------------------------------------------------------------- CMapClass::~CMapClass(void) { // Delete all of our children. m_Children.PurgeAndDeleteElements(); delete m_pEditorKeys; // In case any CMapDocs are pointing at us, let them know we're gone. m_pSafeObject->m_pObject = NULL; // Show a warning if anyone is left pointing at us. static bool bCheckSafeObjects = true; if ( bCheckSafeObjects && m_pSafeObject->GetRefCount() != 1 ) { int ret = AfxMessageBox( "Warning: a CMapClass is being deleted but is still referenced by a CMapDoc.\n" "Please tell a programmer.\n" "Click Yes to write a minidump and continue.\n" "Click No to ignore.", MB_YESNO ); if ( ret == IDYES ) { WriteMiniDump(); } else if ( ret == IDNO ) { // Ignore it and don't get in here again. bCheckSafeObjects = false; } } }
void GenerateMiniDumpFromCtrlBreak() { HMODULE hKernel = GetModuleHandle(L"kernel32.dll"); typedef BOOL (WINAPI* DebugBreakProcess_t)(HANDLE Process); DebugBreakProcess_t DebugBreakProcess_f = (DebugBreakProcess_t)(hKernel ? GetProcAddress(hKernel, "DebugBreakProcess") : NULL); if (DebugBreakProcess_f) { _printf("ConEmuC: Sending DebugBreak event to process\n"); gpSrv->DbgInfo.bDebuggerRequestDump = TRUE; DWORD dwErr = 0; _ASSERTE(gpSrv->hRootProcess!=NULL); if (!DebugBreakProcess_f(gpSrv->hRootProcess)) { dwErr = GetLastError(); //_ASSERTE(FALSE && dwErr==0); _printf("ConEmuC: Sending DebugBreak event failed, Code=x%X, WriteMiniDump on the fly\n", dwErr); gpSrv->DbgInfo.bDebuggerRequestDump = FALSE; WriteMiniDump(gpSrv->dwRootProcess, gpSrv->dwRootThread, NULL); } } else { _printf("ConEmuC: DebugBreakProcess not found in kernel32.dll\n"); } }
LONG __stdcall exception_filter(EXCEPTION_POINTERS* exceptionPtrs) { LONG returnCode = EXCEPTION_CONTINUE_SEARCH; // Ignore multiple calls. if (s_inFilter != 0) return EXCEPTION_CONTINUE_EXECUTION; s_inFilter = 1; // Cannot really do much in case of stack overflow, it'll probably bomb soon // anyway. if (exceptionPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { OutputDebugString("*** FATAL ERROR: EXCEPTION_STACK_OVERFLOW detected!"); } const bool miniDumpOK = WriteMiniDump(exceptionPtrs, s_miniDumpFileName); FILE* f = ::fopen(s_reportFileName, "wt"); WriteHeader(f); WriteExceptionInfo(f, exceptionPtrs); WriteCallStack(f, exceptionPtrs->ContextRecord); WriteEnvironmentInfo(f); MemoryStatus memStatus = MemoryStatus::GetCurrent(); WriteMemoryStatus(f, memStatus); WriteRegisters(f, exceptionPtrs); WriteBlackBoxMessages(f); fprintf(f, (miniDumpOK ? "\nMini dump saved successfully.\n" : "\nFailed to save minidump.\n")); ::fclose(f); return returnCode; }
void _ExitOnFatalAssert( const tchar* pFile, int line ) { _SpewMessage( _T("Fatal assert failed: %s, line %d. Application exiting.\n"), pFile, line ); // only write out minidumps if we're not in the debugger if ( !Plat_IsInDebugSession() ) { WriteMiniDump(); } DevMsg( 1, _T("_ExitOnFatalAssert\n") ); exit( EXIT_FAILURE ); }
// Write a minidump file, unless running under the debugger in which case break // into the debugger. // The "int dummy" parameter is so that the callers can be unique so that the // linker won't use its /opt:icf optimization to collapse them together. This // makes reading the call stack easier. void __cdecl WriteMiniDumpOrBreak( int dummy, const char *pchName ) { if ( Plat_IsInDebugSession() ) { __debugbreak(); // Continue at your peril... } else { WriteMiniDump( pchName ); // Call Plat_ExitProcess so we don't continue in a bad state. TerminateProcess(GetCurrentProcess(), 0); } }
int KDumpFile::MakeDump(const TCHAR szVersion[], const TCHAR szPath[]) { int nResult = FALSE; int nRetCode = FALSE; ASSERT(szVersion && szPath); nRetCode = MakeDumpKey(szVersion); KG_PROCESS_ERROR(nRetCode); nRetCode = WriteMiniDump(szPath); KG_PROCESS_ERROR(nRetCode); nResult = TRUE; Exit0: return nResult; }
bool WriteFullDump() { HINSTANCE hDbgHelp = ::LoadLibrary(_T("dbghelp.dll")); if (hDbgHelp == NULL) return false; pfnMiniDumpWriteDump = (fnMiniDumpWriteDump)::GetProcAddress (hDbgHelp, "MiniDumpWriteDump"); if (pfnMiniDumpWriteDump == NULL) { ::FreeLibrary(hDbgHelp); return false; } TCHAR FullPath[MAX_PATH]; MakeSpecialName(FullPath, MAX_PATH, g_suffix, _T("full.dmp")); bool full = WriteMiniDump(NULL, FullPath, MiniDumpWithFullMemory); ::FreeLibrary (hDbgHelp); return full; }
void ProcessDebugEvent() { static wchar_t wszDbgText[1024]; static char szDbgText[1024]; BOOL lbNonContinuable = FALSE; DEBUG_EVENT evt = {0}; BOOL lbEvent = WaitForDebugEvent(&evt,10); #ifdef _DEBUG DWORD dwErr = GetLastError(); #endif static bool bFirstExitThreadEvent = false; // Чтобы вывести на экран подсказку по возможностям "дебаггера" //HMODULE hCOMDLG32 = NULL; //typedef BOOL (WINAPI* GetSaveFileName_t)(LPOPENFILENAMEW lpofn); //GetSaveFileName_t _GetSaveFileName = NULL; DWORD dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; if (lbEvent) { lbNonContinuable = FALSE; switch (evt.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: case CREATE_THREAD_DEBUG_EVENT: case EXIT_PROCESS_DEBUG_EVENT: case EXIT_THREAD_DEBUG_EVENT: case RIP_EVENT: { LPCSTR pszName = "Unknown"; switch (evt.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: pszName = "CREATE_PROCESS_DEBUG_EVENT"; break; case CREATE_THREAD_DEBUG_EVENT: pszName = "CREATE_THREAD_DEBUG_EVENT"; break; case EXIT_PROCESS_DEBUG_EVENT: pszName = "EXIT_PROCESS_DEBUG_EVENT"; break; case EXIT_THREAD_DEBUG_EVENT: pszName = "EXIT_THREAD_DEBUG_EVENT"; break; case RIP_EVENT: pszName = "RIP_EVENT"; break; } _wsprintfA(szDbgText, SKIPLEN(countof(szDbgText)) "{%i.%i} %s\n", evt.dwProcessId,evt.dwThreadId, pszName); _printf(szDbgText); if (!bFirstExitThreadEvent && evt.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT) { bFirstExitThreadEvent = true; if (gpSrv->DbgInfo.nDebugDumpProcess == 0) { _printf("ConEmuC: Press Ctrl+Break to create minidump of debugging process\n"); } else { // Сразу сделать дамп и выйти HandlerRoutine(CTRL_BREAK_EVENT); } } if (evt.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) { gpSrv->DbgInfo.nProcessCount++; _ASSERTE(gpSrv->DbgInfo.pDebugTreeProcesses!=NULL); CEDebugProcessInfo pi = {evt.dwProcessId}; gpSrv->DbgInfo.pDebugTreeProcesses->Set(evt.dwProcessId, pi); UpdateDebuggerTitle(); } else if (evt.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) { CEDebugProcessInfo pi = {}; if (gpSrv->DbgInfo.pDebugTreeProcesses && gpSrv->DbgInfo.pDebugTreeProcesses->Get(evt.dwProcessId, &pi, true) && pi.hProcess) { CloseHandle(pi.hProcess); } if (gpSrv->DbgInfo.nProcessCount > 0) gpSrv->DbgInfo.nProcessCount--; UpdateDebuggerTitle(); } break; } case LOAD_DLL_DEBUG_EVENT: case UNLOAD_DLL_DEBUG_EVENT: { LPCSTR pszName = "Unknown"; char szBase[32] = {}; char szFile[MAX_PATH+128] = {}; struct MY_FILE_NAME_INFO { DWORD FileNameLength; WCHAR FileName[1]; }; typedef BOOL (WINAPI* GetFileInformationByHandleEx_t)(HANDLE hFile, int FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize); static GetFileInformationByHandleEx_t _GetFileInformationByHandleEx = NULL; switch (evt.dwDebugEventCode) { case LOAD_DLL_DEBUG_EVENT: //6 Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure. pszName = "LOAD_DLL_DEBUG_EVENT"; if (evt.u.LoadDll.hFile) { if (gnOsVer >= 0x0600) { if (!_GetFileInformationByHandleEx) _GetFileInformationByHandleEx = (GetFileInformationByHandleEx_t)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetFileInformationByHandleEx"); if (_GetFileInformationByHandleEx) { DWORD nSize = sizeof(MY_FILE_NAME_INFO)+MAX_PATH*sizeof(wchar_t); MY_FILE_NAME_INFO* pfi = (MY_FILE_NAME_INFO*)calloc(nSize+2,1); if (pfi) { pfi->FileNameLength = MAX_PATH; if (_GetFileInformationByHandleEx(evt.u.LoadDll.hFile, 2/*FileNameInfo*/, pfi, nSize) && pfi->FileName[0]) { wchar_t szFullPath[MAX_PATH+1] = {}, *pszFile; DWORD n = GetFullPathName(pfi->FileName, countof(szFullPath), szFullPath, &pszFile); if (!n || (n >= countof(szFullPath))) { lstrcpyn(szFullPath, pfi->FileName, countof(szFullPath)); pszFile = (wchar_t*)PointToName(pfi->FileName); } else if (!pszFile) { pszFile = (wchar_t*)PointToName(szFullPath); } lstrcpyA(szFile, ", "); WideCharToMultiByte(CP_OEMCP, 0, pszFile, -1, szFile+lstrlenA(szFile), 80, 0,0); lstrcatA(szFile, "\n\t"); WideCharToMultiByte(CP_OEMCP, 0, szFullPath, -1, szFile+lstrlenA(szFile), MAX_PATH, 0,0); } free(pfi); } } } CloseHandle(evt.u.LoadDll.hFile); } _wsprintfA(szBase, SKIPLEN(countof(szBase)) " at " WIN3264TEST("0x%08X","0x%08X%08X"), WIN3264WSPRINT((DWORD_PTR)evt.u.LoadDll.lpBaseOfDll)); break; case UNLOAD_DLL_DEBUG_EVENT: //7 Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure. pszName = "UNLOAD_DLL_DEBUG_EVENT"; _wsprintfA(szBase, SKIPLEN(countof(szBase)) " at " WIN3264TEST("0x%08X","0x%08X%08X"), WIN3264WSPRINT((DWORD_PTR)evt.u.UnloadDll.lpBaseOfDll)); break; } _wsprintfA(szDbgText, SKIPLEN(countof(szDbgText)) "{%i.%i} %s%s%s\n", evt.dwProcessId,evt.dwThreadId, pszName, szBase, szFile); _printf(szDbgText); break; } case EXCEPTION_DEBUG_EVENT: //1 Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure. { lbNonContinuable = (evt.u.Exception.ExceptionRecord.ExceptionFlags&EXCEPTION_NONCONTINUABLE)==EXCEPTION_NONCONTINUABLE; //static bool bAttachEventRecieved = false; //if (!bAttachEventRecieved) //{ // bAttachEventRecieved = true; // StringCchPrintfA(szDbgText, countof(szDbgText),"{%i.%i} Debugger attached successfully. (0x%08X address 0x%08X flags 0x%08X%s)\n", // evt.dwProcessId,evt.dwThreadId, // evt.u.Exception.ExceptionRecord.ExceptionCode, // evt.u.Exception.ExceptionRecord.ExceptionAddress, // evt.u.Exception.ExceptionRecord.ExceptionFlags, // (evt.u.Exception.ExceptionRecord.ExceptionFlags&EXCEPTION_NONCONTINUABLE) ? "(EXCEPTION_NONCONTINUABLE)" : ""); //} //else switch (evt.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: // The thread tried to read from or write to a virtual address for which it does not have the appropriate access. { if (evt.u.Exception.ExceptionRecord.NumberParameters>=2) { _wsprintfA(szDbgText, SKIPLEN(countof(szDbgText)) "{%i.%i} EXCEPTION_ACCESS_VIOLATION at " WIN3264TEST("0x%08X","0x%08X%08X") " flags 0x%08X%s %s of " WIN3264TEST("0x%08X","0x%08X%08X") " FC=%u\n", evt.dwProcessId,evt.dwThreadId, WIN3264WSPRINT((DWORD_PTR)evt.u.Exception.ExceptionRecord.ExceptionAddress), evt.u.Exception.ExceptionRecord.ExceptionFlags, ((evt.u.Exception.ExceptionRecord.ExceptionFlags&EXCEPTION_NONCONTINUABLE) ? "(EXCEPTION_NONCONTINUABLE)" : ""), ((evt.u.Exception.ExceptionRecord.ExceptionInformation[0]==0) ? "Read" : (evt.u.Exception.ExceptionRecord.ExceptionInformation[0]==1) ? "Write" : (evt.u.Exception.ExceptionRecord.ExceptionInformation[0]==8) ? "DEP" : "???"), WIN3264WSPRINT(evt.u.Exception.ExceptionRecord.ExceptionInformation[1]), evt.u.Exception.dwFirstChance ); } else { _wsprintfA(szDbgText, SKIPLEN(countof(szDbgText)) "{%i.%i} EXCEPTION_ACCESS_VIOLATION at " WIN3264TEST("0x%08X","0x%08X%08X") " flags 0x%08X%s FC=%u\n", evt.dwProcessId,evt.dwThreadId, WIN3264WSPRINT((DWORD_PTR)evt.u.Exception.ExceptionRecord.ExceptionAddress), evt.u.Exception.ExceptionRecord.ExceptionFlags, (evt.u.Exception.ExceptionRecord.ExceptionFlags&EXCEPTION_NONCONTINUABLE) ? "(EXCEPTION_NONCONTINUABLE)" : "", evt.u.Exception.dwFirstChance); } _printf(szDbgText); } break; default: { char szName[32]; LPCSTR pszName; pszName = szName; #define EXCASE(s) case s: pszName = #s; break switch(evt.u.Exception.ExceptionRecord.ExceptionCode) { EXCASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED); // The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking. EXCASE(EXCEPTION_BREAKPOINT); // A breakpoint was encountered. EXCASE(EXCEPTION_DATATYPE_MISALIGNMENT); // The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on. EXCASE(EXCEPTION_FLT_DENORMAL_OPERAND); // One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value. EXCASE(EXCEPTION_FLT_DIVIDE_BY_ZERO); // The thread tried to divide a floating-point value by a floating-point divisor of zero. EXCASE(EXCEPTION_FLT_INEXACT_RESULT); // The result of a floating-point operation cannot be represented exactly as a decimal fraction. EXCASE(EXCEPTION_FLT_INVALID_OPERATION); // This exception represents any floating-point exception not included in this list. EXCASE(EXCEPTION_FLT_OVERFLOW); // The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type. EXCASE(EXCEPTION_FLT_STACK_CHECK); // The stack overflowed or underflowed as the result of a floating-point operation. EXCASE(EXCEPTION_FLT_UNDERFLOW); // The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type. EXCASE(EXCEPTION_ILLEGAL_INSTRUCTION); // The thread tried to execute an invalid instruction. EXCASE(EXCEPTION_IN_PAGE_ERROR); // The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network. EXCASE(EXCEPTION_INT_DIVIDE_BY_ZERO); // The thread tried to divide an integer value by an integer divisor of zero. EXCASE(EXCEPTION_INT_OVERFLOW); // The result of an integer operation caused a carry out of the most significant bit of the result. EXCASE(EXCEPTION_INVALID_DISPOSITION); // An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception. EXCASE(EXCEPTION_NONCONTINUABLE_EXCEPTION); // The thread tried to continue execution after a noncontinuable exception occurred. EXCASE(EXCEPTION_PRIV_INSTRUCTION); // The thread tried to execute an instruction whose operation is not allowed in the current machine mode. EXCASE(EXCEPTION_SINGLE_STEP); // A trace trap or other single-instruction mechanism signaled that one instruction has been executed. EXCASE(EXCEPTION_STACK_OVERFLOW); // The thread used up its stack. default: _wsprintfA(szName, SKIPLEN(countof(szName)) "Exception 0x%08X", evt.u.Exception.ExceptionRecord.ExceptionCode); } _wsprintfA(szDbgText, SKIPLEN(countof(szDbgText)) "{%i.%i} %s at " WIN3264TEST("0x%08X","0x%08X%08X") " flags 0x%08X%s FC=%u\n", evt.dwProcessId,evt.dwThreadId, pszName, WIN3264WSPRINT((DWORD_PTR)evt.u.Exception.ExceptionRecord.ExceptionAddress), evt.u.Exception.ExceptionRecord.ExceptionFlags, (evt.u.Exception.ExceptionRecord.ExceptionFlags&EXCEPTION_NONCONTINUABLE) ? "(EXCEPTION_NONCONTINUABLE)" : "", evt.u.Exception.dwFirstChance); _printf(szDbgText); } } BOOL bDumpOnBreakPoint = gpSrv->DbgInfo.bDebuggerRequestDump; if (gpSrv->DbgInfo.bDebugProcessTree && (!lbNonContinuable && (evt.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT))) { // Когда отладчик цепляется к процессу в первый раз - возникает EXCEPTION_BREAKPOINT CEDebugProcessInfo pi = {}; if (gpSrv->DbgInfo.pDebugTreeProcesses && gpSrv->DbgInfo.pDebugTreeProcesses->Get(evt.dwProcessId, &pi)) { if (!pi.bWasBreak) { pi.bWasBreak = TRUE; gpSrv->DbgInfo.pDebugTreeProcesses->Set(evt.dwProcessId, pi); } else { bDumpOnBreakPoint = TRUE; } } } if (gpSrv->DbgInfo.bDebuggerRequestDump || (!lbNonContinuable && !gpSrv->DbgInfo.bDebugProcessTree && (evt.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT)) || (gpSrv->DbgInfo.bDebugProcessTree && ((evt.u.Exception.ExceptionRecord.ExceptionCode>=0xC0000000) || (bDumpOnBreakPoint && (evt.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)))) ) { BOOL bGenerateTreeBreak = gpSrv->DbgInfo.bDebugProcessTree && (gpSrv->DbgInfo.bDebuggerRequestDump || lbNonContinuable); if (gpSrv->DbgInfo.bDebugProcessTree && !bGenerateTreeBreak && (evt.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)) { if (gpSrv->DbgInfo.nWaitTreeBreaks == 0) { bGenerateTreeBreak = TRUE; gpSrv->DbgInfo.nWaitTreeBreaks++; } } gpSrv->DbgInfo.bDebuggerRequestDump = FALSE; // один раз char szConfirm[2048]; if (evt.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) { if (gpSrv->DbgInfo.nDebugDumpProcess) szConfirm[0] = 0; else lstrcpynA(szConfirm, szDbgText, countof(szConfirm)); } else { _wsprintfA(szConfirm, SKIPLEN(countof(szConfirm)) "%s exception (FC=%u)\n", lbNonContinuable ? "Non continuable" : "Continuable", evt.u.Exception.dwFirstChance); StringCchCatA(szConfirm, countof(szConfirm), szDbgText); } StringCchCatA(szConfirm, countof(szConfirm), "\nCreate minidump (<No> - fulldump)?"); //GenerateTreeDebugBreak WriteMiniDump(evt.dwProcessId, evt.dwThreadId, &evt.u.Exception.ExceptionRecord, szConfirm, bGenerateTreeBreak); if (gpSrv->DbgInfo.bDebugProcessTree && (evt.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)) { if (gpSrv->DbgInfo.nWaitTreeBreaks > 0) gpSrv->DbgInfo.nWaitTreeBreaks--; } } if (!lbNonContinuable /*|| (evt.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)*/) { dwContinueStatus = DBG_CONTINUE; } } break; case OUTPUT_DEBUG_STRING_EVENT: //8 Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure. { wszDbgText[0] = 0; if (evt.u.DebugString.nDebugStringLength >= 1024) evt.u.DebugString.nDebugStringLength = 1023; DWORD_PTR nRead = 0; HANDLE hProcess = GetProcessHandleForDebug(evt.dwProcessId); if (evt.u.DebugString.fUnicode) { if (!ReadProcessMemory(hProcess, evt.u.DebugString.lpDebugStringData, wszDbgText, 2*evt.u.DebugString.nDebugStringLength, &nRead)) { wcscpy_c(wszDbgText, L"???"); } else { wszDbgText[min(1023,nRead+1)] = 0; } static int nPrefixLen = lstrlen(CONEMU_CONHOST_CREATED_MSG); if (memcmp(wszDbgText, CONEMU_CONHOST_CREATED_MSG, nPrefixLen*sizeof(wszDbgText[0])) == 0) { LPWSTR pszEnd = NULL; DWORD nConHostPID = wcstoul(wszDbgText+nPrefixLen, &pszEnd, 10); if (nConHostPID && !gpSrv->DbgInfo.pDebugTreeProcesses->Get(nConHostPID, NULL)) { AttachConHost(nConHostPID); } } } else { if (!ReadProcessMemory(hProcess, evt.u.DebugString.lpDebugStringData, szDbgText, evt.u.DebugString.nDebugStringLength, &nRead)) { wcscpy_c(wszDbgText, L"???"); } else { szDbgText[min(1023,nRead+1)] = 0; // CP_ACP differs from CP_OEMCP, thats why we need some overhead... MultiByteToWideChar(CP_ACP, 0, szDbgText, -1, wszDbgText, 1024); } } WideCharToMultiByte(CP_OEMCP, 0, wszDbgText, -1, szDbgText, 1024, 0, 0); #ifdef CRTPRINTF { _printf("{PID=%i.TID=%i} ", evt.dwProcessId,evt.dwThreadId, wszDbgText); } #else { _printf("{PID=%i.TID=%i} %s", evt.dwProcessId,evt.dwThreadId, szDbgText); int nLen = lstrlenA(szDbgText); if (nLen > 0 && szDbgText[nLen-1] != '\n') _printf("\n"); } #endif dwContinueStatus = DBG_CONTINUE; } break; } // Продолжить отлаживаемый процесс ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, dwContinueStatus); } //if (hCOMDLG32) // FreeLibrary(hCOMDLG32); }
static LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS *ExceptionPointers) { if( g_NoExceptions ) { static bool g_here = false; if( !g_here ) { g_here = true; PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "Unhandled exception 0x%x occured at address 0x%x", ExceptionPointers->ExceptionRecord->ExceptionCode, ExceptionPointers->ExceptionRecord->ExceptionAddress)); } TerminateProcess(GetCurrentProcess(), 0); return EXCEPTION_EXECUTE_HANDLER; } // first notify driver of our crash PVOID pDrvContext = NULL; HRESULT hResult = DRV_Register( &pDrvContext, AVPG_Driver_Specific, AVPG_INFOPRIORITY, _CLIENT_FLAG_POPUP_TYPE | _CLIENT_FLAG_WITHOUTWATCHDOG, 0, 0, MemAlloc, MemFree, NULL); if (SUCCEEDED( hResult )) { DRV_DisconnectAllClients( pDrvContext ); DRV_UnRegister( &pDrvContext ); } static DWORD dwWriteMiniDumpRes = 0; static DWORD dummy; static HANDLE hThread; if (ExceptionPointers != NULL && ExceptionPointers->ExceptionRecord != NULL && ExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW && (hThread = CreateThread(NULL, 0, WriteMiniDumpThread, ExceptionPointers, 0, &dummy)) != NULL) { WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &dwWriteMiniDumpRes); } else dwWriteMiniDumpRes = WriteMiniDump(ExceptionPointers) ? 1 : 0; if (ExceptionPointers == NULL || ExceptionPointers->ExceptionRecord == NULL) return EXCEPTION_CONTINUE_SEARCH; TCHAR ExceptionLogFileName[MAX_PATH]; MakeSpecialName(ExceptionLogFileName, MAX_PATH, g_suffix, _T("exception.log")); HANDLE hFile = CreateFile(ExceptionLogFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL); if (hFile == INVALID_HANDLE_VALUE) return EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD er = ExceptionPointers->ExceptionRecord; DWORD dwNumBytesWritten; char msg[512]; wsprintf(msg, _T("Unhandled exception %#08x occured\n"), er->ExceptionCode); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); do { wsprintf (msg, _T("EXCEPTION_RECORD ===============\n")); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); wsprintf (msg, _T("Code = %#08x\n"), er->ExceptionCode); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); wsprintf (msg, _T("Flags = %#08x\n"), er->ExceptionFlags); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); wsprintf (msg, _T("Address = %#08x\n"), (LONG)er->ExceptionAddress); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); for (DWORD i = 0; i < er->NumberParameters; ++i) { wsprintf (msg, _T("Parameter %d = %#08x\n"), i, er->ExceptionInformation[i]); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); } wsprintf (msg, _T("================================\n")); WriteFile(hFile, msg, _tcslen (msg), &dwNumBytesWritten, NULL); PR_TRACE((NULL, prtALWAYS_REPORTED_MSG, "%s", msg)); } while ((er = er->ExceptionRecord) != NULL); CloseHandle (hFile); if(g_hTraceFile) FlushFileBuffers(g_hTraceFile); _wmih_UpdateStatus(VER_PRODUCT_WMIH_ID, wmicAntiVirus, 0); _wmih_UpdateStatus(VER_PRODUCT_WMIH_ID, wmicAntiHaker, 0); _wmih_UpdateStatus(VER_PRODUCT_WMIH_ID, wmicAntiSpyWare, 0); return EXCEPTION_CONTINUE_SEARCH; }
//-- static DWORD WINAPI WriteMiniDumpThread(LPVOID lpParameter) { return WriteMiniDump((EXCEPTION_POINTERS*)lpParameter) ? 1 : 0; }