VOID Get_Exception_Info(PEXCEPTION_POINTERS pException, FILE* fp, UINT dwLastError) { CHAR Module_Name[MAX_PATH]; PBYTE Module_Addr; HANDLE hFile; FILETIME Last_Write_Time; FILETIME Local_File_Time; SYSTEMTIME T; Get_Version_Str(fp); _ftprintf(fp, _T("------------------------------------------------------------------------------\n")); _ftprintf(fp, _T("Process: ") ); GetModuleFileName(NULL, Module_Name, MAX_PATH); _ftprintf(fp, _T("%s\n") , Module_Name); // If exception occurred. if (pException) { EXCEPTION_RECORD & E = *pException->ExceptionRecord; CONTEXT & C = *pException->ContextRecord; // If module with E.ExceptionAddress found - save its path and date. if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) { _ftprintf(fp, _T("Module: %s\n") , Module_Name); if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time)) { FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time); FileTimeToSystemTime(&Local_File_Time, &T); _ftprintf(fp, _T("Date Modified: %02d/%02d/%d\n") , T.wMonth, T.wDay, T.wYear); } CloseHandle(hFile); } } else { _ftprintf(fp, _T("Exception Addr: %08X\n") , (LONG_PTR)(E.ExceptionAddress)); } _ftprintf(fp, _T("------------------------------------------------------------------------------\n")); //加入具体异常解释信息 CreateExceptionDesc(pException, fp, dwLastError); } _ftprintf(fp, _T("------------------------------------------------------------------------------\n")); // Save call stack info. _ftprintf(fp, _T("Call Stack:\n")); Get_Call_Stack(pException, fp); }
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { if(lpTopLevelExceptionFilter == gFilterFunc) return gFilterFunc; llinfos << "Someone tried to set the exception filter. Listing call stack modules" << llendl; LLSD cs_info; Get_Call_Stack(NULL, NULL, cs_info); if(cs_info.has("CallStack") && cs_info["CallStack"].isArray()) { LLSD cs = cs_info["CallStack"]; for(LLSD::array_iterator i = cs.beginArray(); i != cs.endArray(); ++i) { llinfos << "Module: " << (*i)["ModuleName"] << llendl; } } return gFilterFunc; }
BOOL GetThreadCallStack(DWORD thread_id, LLSD& info) { if(GetCurrentThreadId() == thread_id) { // Early exit for the current thread. // Suspending the current thread would be a bad idea. // Plus you can't retrieve a valid current thread context. return false; } HANDLE thread_handle = INVALID_HANDLE_VALUE; thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); if(INVALID_HANDLE_VALUE == thread_handle) { return FALSE; } BOOL result = false; if(-1 != SuspendThread(thread_handle)) { CONTEXT context_struct; context_struct.ContextFlags = CONTEXT_FULL; if(GetThreadContext(thread_handle, &context_struct)) { Get_Call_Stack(NULL, &context_struct, info); result = true; } ResumeThread(thread_handle); } else { // Couldn't suspend thread. } CloseHandle(thread_handle); return result; }
//************************************************************* void Get_Exception_Info(PEXCEPTION_POINTERS pException, FILE* fp, DWORD dwLastError) //************************************************************* // Allocate Str[DUMP_SIZE_MAX] and return Str with dump, if !pException - just return call stack in Str. { int i; TCHAR Module_Name[MAX_PATH]; PBYTE Module_Addr; HANDLE hFile; FILETIME Last_Write_Time; FILETIME Local_File_Time; SYSTEMTIME T; Get_Version_Str(fp); _ftprintf(fp, _T("------------------------------------------------------------------------------")NL); _ftprintf(fp, _T("Process: ") ); GetModuleFileName(NULL, Module_Name, MAX_PATH); _ftprintf(fp, _T("%s") NL, Module_Name); // If exception occurred. if (pException) { EXCEPTION_RECORD & E = *pException->ExceptionRecord; CONTEXT & C = *pException->ContextRecord; // If module with E.ExceptionAddress found - save its path and date. if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) { _ftprintf(fp, _T("Module: %s") NL, Module_Name); if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time)) { FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time); FileTimeToSystemTime(&Local_File_Time, &T); _ftprintf(fp, _T("Date Modified: %02d/%02d/%d") NL, T.wMonth, T.wDay, T.wYear); } CloseHandle(hFile); } } else { _ftprintf(fp, _T("Exception Addr: %08X") NL , (LONG_PTR)(E.ExceptionAddress)); } _ftprintf(fp, _T("------------------------------------------------------------------------------")NL); //加入具体异常解释信息 CreateExceptionDesc(pException, fp, dwLastError); _ftprintf(fp, _T("------------------------------------------------------------------------------")NL); // Save instruction that caused exception. if(E.ExceptionAddress) { _ftprintf(fp, _T("Instruction: ")NL); for (i = 0; i < 16; i++) _ftprintf(fp, _T(" %02X"), PBYTE(E.ExceptionAddress)[i]); } // Save registers at exception. _ftprintf(fp, NL _T("Registers:") NL); _ftprintf(fp, _T("EAX: %08X EBX: %08X ECX: %08X EDX: %08X") NL, C.Eax, C.Ebx, C.Ecx, C.Edx); _ftprintf(fp, _T("ESI: %08X EDI: %08X ESP: %08X EBP: %08X")NL, C.Esi, C.Edi, C.Esp, C.Ebp); _ftprintf(fp, _T("EIP: %08X EFlags: %08X")NL, C.Eip, C.EFlags); } //if (pException) _ftprintf(fp, _T("------------------------------------------------------------------------------")NL); // Save call stack info. _ftprintf(fp, _T("Call Stack:")NL); Get_Call_Stack(pException, fp); } //Get_Exception_Info
//************************************************************* LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException) //************************************************************* // Allocate Str[DUMP_SIZE_MAX] and return Str with dump, if !pException - just return call stack in Str. { LLSD info; LPWSTR Str; int Str_Len; // int i; LPWSTR Module_Name = new WCHAR[MAX_PATH]; PBYTE Module_Addr; HANDLE hFile; FILETIME Last_Write_Time; FILETIME Local_File_Time; SYSTEMTIME T; Str = new WCHAR[DUMP_SIZE_MAX]; Str_Len = 0; if (!Str) return NULL; Get_Version_Str(info); GetModuleFileName(NULL, Str, MAX_PATH); info["Process"] = ll_convert_wide_to_string(Str); info["ThreadID"] = (S32)GetCurrentThreadId(); // If exception occurred. if (pException) { EXCEPTION_RECORD & E = *pException->ExceptionRecord; CONTEXT & C = *pException->ContextRecord; // If module with E.ExceptionAddress found - save its path and date. if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) { info["Module"] = ll_convert_wide_to_string(Module_Name); if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time)) { FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time); FileTimeToSystemTime(&Local_File_Time, &T); info["DateModified"] = llformat("%02d/%02d/%d", T.wMonth, T.wDay, T.wYear); } CloseHandle(hFile); } } else { info["ExceptionAddr"] = (int)E.ExceptionAddress; } info["ExceptionCode"] = (int)E.ExceptionCode; /* //TODO: Fix this if (E.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { // Access violation type - Write/Read. LLSD exception_info; exception_info["Type"] = E.ExceptionInformation[0] ? "Write" : "Read"; exception_info["Address"] = llformat("%08x", E.ExceptionInformation[1]); info["Exception Information"] = exception_info; } */ // Save instruction that caused exception. /* std::string str; for (i = 0; i < 16; i++) str += llformat(" %02X", PBYTE(E.ExceptionAddress)[i]); info["Instruction"] = str; */ LLSD registers; registers["EAX"] = (int)C.Eax; registers["EBX"] = (int)C.Ebx; registers["ECX"] = (int)C.Ecx; registers["EDX"] = (int)C.Edx; registers["ESI"] = (int)C.Esi; registers["EDI"] = (int)C.Edi; registers["ESP"] = (int)C.Esp; registers["EBP"] = (int)C.Ebp; registers["EIP"] = (int)C.Eip; registers["EFlags"] = (int)C.EFlags; info["Registers"] = registers; } //if (pException) // Save call stack info. Get_Call_Stack(pException->ExceptionRecord, pException->ContextRecord, info); return info; } //Get_Exception_Info