/*
 *  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());
    }
}
示例#2
0
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(".");
}
示例#4
0
/*
 * 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 */