void minios_do_halt(int reason) { minios_printk("minios: halting, reason=%d\n", reason); for( ;; ) { struct sched_shutdown sched_shutdown = { .reason = (reason == MINIOS_HALT_POWEROFF) ? SHUTDOWN_poweroff : SHUTDOWN_crash }; HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); } } /* * do_exit: This is called whenever an IRET fails in entry.S. * This will generally be because an application has got itself into * a really bad state (probably a bad CS or SS). It must be killed. * Of course, minimal OS doesn't have applications :-) */ void minios_do_exit(void) { minios_printk("Do_exit called!\n"); stack_walk(); for( ;; ) { struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash }; HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); } }
void do_exit(void) { printk("Do_exit called!\n"); stack_walk(); for( ;; ) { struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash }; HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); } }
static std::list<stack_info> get_stack_list( void* bp, void* sp, void* ip, size_t max_depth, size_t offset, bool module, bool symbol, bool brief ) { QWORD trace[33]; CONTEXT context; ZeroMemory(&context, sizeof(context)); context.ContextFlags = CONTEXT_FULL; #ifdef _WIN64 context.Rbp = (DWORD64)bp; context.Rsp = (DWORD64)sp; context.Rip = (DWORD64)ip; #else context.Ebp = (DWORD)bp; context.Esp = (DWORD)sp; context.Eip = (DWORD)ip; #endif size_t depths = stack_walk(trace, max_depth, &context); std::list<stack_info> image_list; HANDLE hProcess = GetCurrentProcess(); for (size_t i = offset; i < depths; i++) { stack_info stack_result(brief); { DWORD symbolDisplacement = 0; IMAGEHLP_LINE64 imageHelpLine; imageHelpLine.SizeOfStruct = sizeof(imageHelpLine); if (SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine)) { stack_result.file_ = std::string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName)); std::memset(imageHelpLine.FileName, 0, stack_result.file_.size() + 1); stack_result.line_ = (int)imageHelpLine.LineNumber; } else { stack_result.line_ = -1; } } if (symbol) { static const int max_name_length = 1024; char symbolBf[sizeof(IMAGEHLP_SYMBOL64) + max_name_length] = { 0 }; PIMAGEHLP_SYMBOL64 symbol; DWORD64 symbolDisplacement64 = 0; symbol = (PIMAGEHLP_SYMBOL64)symbolBf; symbol->SizeOfStruct = sizeof(symbolBf); symbol->MaxNameLength = max_name_length; if (SymGetSymFromAddr64( hProcess, trace[i], &symbolDisplacement64, symbol) ) { stack_result.symbol_ = symbol->Name; } else { stack_result.symbol_ = "unknow..."; } } if (module) { IMAGEHLP_MODULE64 imageHelpModule; imageHelpModule.SizeOfStruct = sizeof(imageHelpModule); if (SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule)) { stack_result.module_ = std::string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName)); std::memset(imageHelpModule.ImageName, 0, stack_result.module_.size() + 1); } } image_list.push_back(std::move(stack_result)); } return image_list; }
////////////////////////////////////////////////////////////////////////// //截获异常信息,并生成自定义的异常报告和弹出窗口 ////////////////////////////////////////////////////////////////////////// LONG WINAPI CustomExceptionFun(struct _EXCEPTION_POINTERS* ExceptionInfo) { SetUnhandledExceptionFilter(NULL); CString logPath,folderPath,errDetail; CString tips; CString strDes,strStack; CTime timer; CStdioFile stFile; TCHAR sz_module[MAX_PATH] = {0}; UINT_PTR section = 0, offset = 0; strDes.Format(L"%s\r\n%s",L"我们很抱歉地通知您,程序遇到错误,不得不终止。",L"以下是该错误的详细信息:"); //werDlg.SetDes(strDes); TCHAR szFileName[MAX_PATH]; ::GetModuleFileName(NULL, szFileName, MAX_PATH); *(_tcsrchr(szFileName, _T('\\')) + 1) = 0; timer = CTime::GetCurrentTime(); folderPath.Format(L"%slog\\",szFileName); logPath.Format(L"%slog\\dump_%d_%d_%d_%d.txt", szFileName, timer.GetYear(), timer.GetMonth(), timer.GetDay(), timer.GetHour()); tips.Format(L"%s\r\n%s",L"以上错误信息保存在:",logPath); g_strErrLogPath = logPath; //生成错误地址 get_logical_address(ExceptionInfo->ExceptionRecord->ExceptionAddress, sz_module, sizeof(sz_module)); //生成堆栈信息 stack_walk(strStack,ExceptionInfo->ContextRecord); //生成寄存器信息 #ifdef _M_IX86 // Intel Only! CString strReg; strReg = L"\nRegisters:\r\n"; strReg.Format(L"%sEAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n", strReg,ExceptionInfo->ContextRecord->Eax, ExceptionInfo->ContextRecord->Ebx, ExceptionInfo->ContextRecord->Ecx, ExceptionInfo->ContextRecord->Edx, ExceptionInfo->ContextRecord->Esi, ExceptionInfo->ContextRecord->Edi ); strReg.Format(L"%sCS:EIP: %04X:%08X\r\n",strReg, ExceptionInfo->ContextRecord->SegCs, ExceptionInfo->ContextRecord->Eip); strReg.Format(L"%sSS:ESP: %04X:%08X \r\nEBP:%08X\r\n",strReg, ExceptionInfo->ContextRecord->SegSs, ExceptionInfo->ContextRecord->Esp, ExceptionInfo->ContextRecord->Ebp ); strReg.Format(L"%sDS:%04X ES:%04X FS:%04X GS:%04X\r\n", strReg,ExceptionInfo->ContextRecord->SegDs, ExceptionInfo->ContextRecord->SegEs, ExceptionInfo->ContextRecord->SegFs, ExceptionInfo->ContextRecord->SegGs ); strReg.Format(L"%sFlags:%08X\r\n",strReg, ExceptionInfo->ContextRecord->EFlags); #endif //_M_IX86 //生成错误详细信息 errDetail.Format(L"Error Code:%x\r\n%s\r\nAddress:%x\r\n%s\r\n\r\n%s\r\n%s", ExceptionInfo->ExceptionRecord->ExceptionCode, get_exception_string(ExceptionInfo->ExceptionRecord->ExceptionCode), ExceptionInfo->ExceptionRecord->ExceptionAddress, sz_module, strReg, strStack); g_strErrDetail = errDetail; //写日志 CFileFind fileFinder; if (!fileFinder.FindFile(folderPath)) { if (::CreateDirectory(folderPath,NULL) < 0) return EXCEPTION_EXECUTE_HANDLER; } if (stFile.Open(logPath,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite | CFile::typeBinary)) { stFile.SeekToEnd(); stFile.Write("\377\376", 2); stFile.WriteString(errDetail); stFile.Close(); } //werDlg.DoModal(); CreateWerWindow(logPath,errDetail); return EXCEPTION_EXECUTE_HANDLER; }