//************************************************************************* // HandleInDebuggerFault() // //************************************************************************* ULONG HandleInDebuggerFault(FRAME* ptr,ULONG address) { PEPROCESS tsk; ENTER_FUNC(); DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while inside debugger, eip: %x\n",address, ptr->eip)); // fault in this page fault handler if(bInPageFaultHandler) { DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while in page fault handler\n",address)); DPRINT((0,"!!! machine is halted !!!\n")); __asm__ __volatile__ ("hlt"); LEAVE_FUNC(); return 0; } bInPageFaultHandler = TRUE; // when we come here from DebuggerShell() we live on a different stack // so the current task is different as well tsk = IoGetCurrentProcess(); DPRINT((0,"%.8X (%.4X:%.8X %.8X %s %s %s task=%.8X )\n", address, ptr->cs, ptr->eip, ptr->eflags, (ptr->error_code&1)?"PLP":"NP", (ptr->error_code&2)?"WRITE":"READ", (ptr->error_code&4)?"USER-MODE":"KERNEL-MODE", (ULONG)tsk)); if(!bInPrintk) { DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler!\n",address)); } else { DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler while in PrintkCallback()!\n",address)); } if(tsk) { PULONG pPGD; PULONG pPTE; pPGD = ADDR_TO_PDE(address); DPRINT((0,"PGD for %.8X @ %.8X = %.8X\n",address,(ULONG)pPGD,(ULONG)(*pPGD) )); if(pPGD && (*pPGD)&_PAGE_PRESENT) { // not large page if(!((*pPGD)&_PAGE_4M)) { pPTE = ADDR_TO_PTE(address); if(pPTE) { DPRINT((0,"PTE for %.8X @ %.8X = %.8X\n",address,(ULONG)pPTE,(ULONG)(*pPTE) )); } } } } IntelStackWalk(ptr->eip,CurrentEBP,ulRealStackPtr); DPRINT((0,"!!! machine is halted !!!\n")); __asm__ __volatile__ ("hlt"); LEAVE_FUNC(); return 2; }
static BOOL StackBackTrace(HANDLE hProcess, HANDLE hThread, PCONTEXT pContext) { STACKFRAME StackFrame; HMODULE hModule = NULL; TCHAR szModule[MAX_PATH]; #ifdef HAVE_BFD bfd *abfd = NULL; asymbol **syms = NULL; // The symbol table. long symcount = 0; // Number of symbols in `syms'. #endif /* HAVE_BFD */ assert(!bSymInitialized); j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); if(j_SymInitialize(hProcess, NULL, TRUE)) bSymInitialized = TRUE; memset( &StackFrame, 0, sizeof(StackFrame) ); // Initialize the STACKFRAME structure for the first call. This is only // necessary for Intel CPUs, and isn't mentioned in the documentation. StackFrame.AddrPC.Offset = pContext->Eip; StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Offset = pContext->Esp; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Offset = pContext->Ebp; StackFrame.AddrFrame.Mode = AddrModeFlat; rprintf( _T("Call stack:\r\n") ); if(0) rprintf( _T("AddrPC AddrReturn AddrFrame AddrStack\r\n") ); while ( 1 ) { BOOL bSuccess = FALSE; #ifdef HAVE_BFD const HMODULE hPrevModule = hModule; #endif /* HAVE_BFD */ TCHAR szSymName[512] = _T(""); TCHAR szFileName[MAX_PATH] = _T(""); DWORD LineNumber = 0; if(bSymInitialized) { if(!j_StackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, j_SymFunctionTableAccess, j_SymGetModuleBase, NULL ) ) break; } else { if(!IntelStackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, NULL, NULL, NULL ) ) break; } // Basic sanity check to make sure the frame is OK. Bail if not. if ( 0 == StackFrame.AddrFrame.Offset ) break; if(0) { rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.AddrPC.Offset, StackFrame.AddrReturn.Offset, StackFrame.AddrFrame.Offset, StackFrame.AddrStack.Offset ); rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3] ); } rprintf( _T("%08lX"), StackFrame.AddrPC.Offset); if((hModule = (HMODULE) GetModuleBase(StackFrame.AddrPC.Offset)) && GetModuleFileName(hModule, szModule, sizeof(szModule))) { #ifndef HAVE_BFD rprintf( _T(" %s:ModulBase %08lX"), szModule, hModule); #else /* HAVE_BFD */ rprintf( _T(" %s:%08lX"), szModule, StackFrame.AddrPC.Offset); if(hModule != hPrevModule) { if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); if((abfd = bfd_openr (szModule, NULL))) if(bfd_check_format(abfd, bfd_object)) { bfd_vma adjust_section_vma = 0; /* If we are adjusting section VMA's, change them all now. Changing the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ if ((adjust_section_vma = (bfd_vma) hModule - pe_data(abfd)->pe_opthdr.ImageBase)) { asection *s; for (s = abfd->sections; s != NULL; s = s->next) { s->vma += adjust_section_vma; s->lma += adjust_section_vma; } } if(bfd_get_file_flags(abfd) & HAS_SYMS) /* Read in the symbol table. */ slurp_symtab(abfd, &syms, &symcount); } } if(!bSuccess && abfd && syms && symcount) if((bSuccess = BfdGetSymFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szSymName, 512))) { /* framepointer = StackFrame.AddrFrame.Offset; hprocess = hProcess; */ BfdDemangleSymName(szSymName, szSymName, 512); rprintf( _T(" %s"), szSymName); if(BfdGetLineFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } #endif /* HAVE_BFD */ if(!bSuccess && bSymInitialized) if((bSuccess = ImagehlpGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) { rprintf( _T(" %s"), szSymName); ImagehlpDemangleSymName(szSymName, szSymName, 512); if(ImagehlpGetLineFromAddr(hProcess, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } if(!bSuccess) if((bSuccess = PEGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) rprintf( _T(" %s"), szSymName); } rprintf(_T("\r\n")); } #ifdef HAVE_BFD if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); #endif /* HAVE_BFD */ if(bSymInitialized) { if(!j_SymCleanup(hProcess)) assert(0); bSymInitialized = FALSE; } return TRUE; }