/* * PrintBacktrace * Prints a call backtrace into the logging buffer */ void ExceptionTracer::PrintBacktrace() { StackTracer tracer(this->context); char module_name[MAX_PATH]; char sym_buffer[sizeof(SYMBOL_INFO) + symbol_max]; int backtrace_count = 0; // Num of frames traced bool has_symbol_api = false; // True if we have the symbol API available for use DWORD old_options; // Saves old symbol API options SYMBOL_INFO& symbol = *(SYMBOL_INFO*)sym_buffer; symbol.SizeOfStruct = sizeof(SYMBOL_INFO); symbol.MaxNameLen = symbol_max; // Tries to get the symbol api if (SymInitialize(GetCurrentProcess(), 0, TRUE)) { has_symbol_api = true; old_options = SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_NO_PROMPTS | SYMOPT_FAIL_CRITICAL_ERRORS); } Print("Backtrace (may be wrong):"); EnterScope(); { // Walks on the stack until there's no frame to trace or we traced 'max_backtrace' frames while (auto trace = tracer.Walk()) { if (++backtrace_count >= max_backtrace) break; bool has_sym = false; // This EIP has a symbol associated with it? DWORD64 displacement; // EIP displacement relative to symbol // If we have access to the symbol api, try to get symbol name from pc (eip) if (has_symbol_api) has_sym = trace->pc ? !!SymFromAddr(GetCurrentProcess(), (DWORD64)trace->pc, &displacement, &symbol) : false; // Print everything up, this.... Ew, this looks awful! Print(backtrace_count == 1 ? "=>" : " "); // First line should have '=>' to specify where it crashed Print("0x%p ", trace->pc); // Print EIP at frame if (has_sym) Print("%s+0x%x ", symbol.Name, (DWORD)displacement); // Print frame func symbol Print("in %s (+0x%x) ", // Print module trace->module ? FindModuleName(trace->module, module_name, sizeof(module_name)) : "unknown", (uintptr_t)(trace->pc) - (uintptr_t)(trace->module) // Module displacement ); if (trace->frame) Print("(0x%p) ", trace->frame); // Print frame pointer NewLine(); } } LeaveScope(); // Cleanup the symbol api if (has_symbol_api) { SymSetOptions(old_options); SymCleanup(GetCurrentProcess()); } }
bool CPythonEngine::InitMainInterp(void) { // ensure only 1 engine/thread initialises this only CSLock l(m_initLock); if (!m_haveInit) { PyGILState_STATE old_state; if (Py_IsInitialized()) old_state = PyGILState_Ensure(); else { Py_Initialize(); old_state = PyGILState_UNLOCKED; } PyEval_InitThreads(); if (!g_IsFrozen) { TCHAR *dll_path = GetModulePath(); AddToPythonPath(dll_path); free(dll_path); PyErr_Clear(); } // isapidllhandle to match dllhandle, frozendllhandle, etc :) Also a // nice way for a program to know they are in an ISAPI context. PyObject *obh = PyLong_FromVoidPtr(g_hInstance); PySys_SetObject("isapidllhandle", obh); Py_XDECREF(obh); // Locate the special exception we use to trigger a reload. PyObject *isapi_package = PyImport_ImportModule("isapi"); if (isapi_package) m_reload_exception = PyObject_GetAttrString(isapi_package, "InternalReloadException"); Py_XDECREF(isapi_package); // ready our types. InitExtensionTypes(); InitFilterTypes(); PyGILState_Release(old_state); FindModuleName(); m_haveInit = true; } return true; }
/* * PrintUnhandledException * Prints the well known "Unhandled exception at ..." into the logging buffer */ void ExceptionTracer::PrintUnhandledException() { char module_name[MAX_PATH]; auto dwExceptionCode = record.ExceptionCode; uintptr_t address = (uintptr_t)record.ExceptionAddress; // Find out our module name for logging if (!this->module || !GetModuleFileNameA(this->module, module_name, sizeof(module_name))) strcpy(module_name, "unknown"); // Log the exception in a similar format similar to debuggers format Print("Unhandled exception at 0x%p in %s", address, FindModuleName(module, module_name, sizeof(module_name))); if (module) Print(" (+0x%x)", address - (uintptr_t)(module)); Print(": 0x%X: %s", dwExceptionCode, GetExceptionCodeString(dwExceptionCode)); // If exception is IN_PAGE_ERROR or ACCESS_VIOLATION, we have additional information such as an address if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR || dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) { auto rw = (DWORD)record.ExceptionInformation[0]; // read or write? auto addr = (ULONG_PTR)record.ExceptionInformation[1]; // which address? Print(" %s 0x%p", rw == 0 ? "reading location" : rw == 1 ? "writing location" : rw == 8 ? "DEP at" : "", addr); // IN_PAGE_ERROR have another information... if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR) { NewLine(); Print("Underlying NTSTATUS code that resulted in the exception is 0x%p", record.ExceptionInformation[2]); } } Print("."); }
/* * InitHeapList - build a heap list */ void InitHeapList( HWND boxhwnd, BOOL keeppos ) { GlobStateStruct state; int htype; HCURSOR hourglass; HCURSOR oldcursor; WORD pos; BOOL ret; hourglass = LoadCursor( NULL, IDC_WAIT ); SetCapture( boxhwnd ); oldcursor= SetCursor( hourglass ); if( keeppos ) { keeppos = SaveGlobalListState( boxhwnd, &state ); } FreeHeapList(); switch( HeapType ) { case HEAPMENU_DISPLAY_ENTIRE: htype = GLOBAL_ALL; break; case HEAPMENU_DISPLAY_LRU: htype = GLOBAL_LRU; break; case HEAPMENU_DISPLAY_FREE: htype = GLOBAL_FREE; break; } if( HeapType != HEAPMENU_DISPLAY_DPMI ) { heap_list hl; ListingDPMI = FALSE; hl.is_dpmi = FALSE; hl.is_added = FALSE; pos = 0; MyGlobalFirst( &hl.info.ge, htype ); do { hl.szModule[0] = 0; hl.lru_pos = pos; if( hl.info.ge.hOwner != NULL ) { FindModuleName( hl.szModule, hl.info.ge.hOwner ); } hl.flag = GetMemFlag( &hl ); ret = AddToHeapList( &hl ); if( !ret ) break; pos ++; } while( MyGlobalNext( &hl.info.ge, htype ) ); } else { ListingDPMI = TRUE; ret = AddAllSelectors( 7 ); if( ret ) { ret = AddAllSelectors( 0 ); } } if( !ret ) { ErrorBox( HeapWalkMainWindow, STR_CANT_CONSTRUCT_GBL_LIST, MB_OK | MB_ICONINFORMATION ); SendMessage( boxhwnd, LB_RESETCONTENT, 0, 0L ); } else { SortHeapList(); ReDisplayHeapList( boxhwnd, keeppos ? &state:NULL ); } SetCursor( oldcursor ); ReleaseCapture(); } /* InitHeapList */