コード例 #1
0
void CrashHandlerWindows::handleCrash(int crashType, void* crashExtraInfo, int FPECode) {

    Autolock autoLock(&m_Lock);

    EXCEPTION_POINTERS* pExceptionPointers = (EXCEPTION_POINTERS*)crashExtraInfo;

    // Run the callbacks
    for(std::vector<CrashHandler::CrashCallback>::iterator it = m_crashCallbacks.begin(); it != m_crashCallbacks.end(); ++it)
        (*it)();

    // Get summary
    getCrashSummary(crashType, FPECode);

    // Write crash dump
    writeCrashDump(pExceptionPointers);

    // Copy CONTEXT to crash info structure
    memset(&m_pCrashInfo->contextRecord, 0, sizeof(m_pCrashInfo->contextRecord));
    if(pExceptionPointers != 0) {
        m_pCrashInfo->exceptionCode = pExceptionPointers->ExceptionRecord->ExceptionCode;
        memcpy(&m_pCrashInfo->contextRecord, pExceptionPointers->ContextRecord, sizeof(m_pCrashInfo->contextRecord));
    } else {
        RtlCaptureContext(&m_pCrashInfo->contextRecord);
    }

    // Get current thread id
    m_pCrashInfo->threadHandle = GetCurrentThread();

    waitForReporter();

    TerminateProcess(GetCurrentProcess(), 1);
}
コード例 #2
0
void CrashHandlerWindows::handleCrash(int crashType, void * crashExtraInfo, int fpeCode) {
	
	Autolock autoLock(&m_Lock);
	
	// Run the callbacks
	for(std::vector<CrashHandler::CrashCallback>::iterator it = m_crashCallbacks.begin();
	    it != m_crashCallbacks.end(); ++it) {
		(*it)();
	}
	
	m_pCrashInfo->signal = crashType;
	m_pCrashInfo->code = fpeCode;
	
	PEXCEPTION_POINTERS pointers = reinterpret_cast<PEXCEPTION_POINTERS>(crashExtraInfo);
	
	// Copy CONTEXT to crash info structure
	PCONTEXT context = reinterpret_cast<PCONTEXT>(m_pCrashInfo->contextRecord);
	ARX_STATIC_ASSERT(sizeof(m_pCrashInfo->contextRecord) >= sizeof(*context),
	                  "buffer too small");
	memset(context, 0, sizeof(*context));
	EXCEPTION_POINTERS fakePointers;
	EXCEPTION_RECORD exception;
	if(pointers) {
		u32 code = m_pCrashInfo->exceptionCode = pointers->ExceptionRecord->ExceptionCode;
		m_pCrashInfo->address = u64(pointers->ExceptionRecord->ExceptionAddress);
		m_pCrashInfo->hasAddress = true;
		if(code == EXCEPTION_ACCESS_VIOLATION || code == EXCEPTION_IN_PAGE_ERROR) {
			m_pCrashInfo->memory = pointers->ExceptionRecord->ExceptionInformation[1];
			m_pCrashInfo->hasMemory = true;
		}
		#if ARX_ARCH == ARX_ARCH_X86
		m_pCrashInfo->stack =  pointers->ContextRecord->Esp;
		m_pCrashInfo->hasStack = true;
		m_pCrashInfo->frame =  pointers->ContextRecord->Ebp;
		m_pCrashInfo->hasFrame = true;
		#elif ARX_ARCH == ARX_ARCH_X86_64
		m_pCrashInfo->stack =  pointers->ContextRecord->Rsp;
		m_pCrashInfo->hasStack = true;
		#endif
		std::memcpy(context, pointers->ContextRecord, sizeof(*context));
	} else {
		RtlCaptureContext(context);
		std::memset(&exception, 0, sizeof(exception));
		fakePointers.ContextRecord = context;
		fakePointers.ExceptionRecord = &exception;
		pointers = &fakePointers;
	}
	
	// Get current thread id
	m_pCrashInfo->threadId = u32(GetCurrentThreadId());
	
	writeCrashDump(pointers);
	
	// Try to spawn a sub-process to process the crash info
	STARTUPINFO si;
	memset(&si, 0, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	PROCESS_INFORMATION pi;
	memset(&pi, 0, sizeof(PROCESS_INFORMATION));
	BOOL created = CreateProcessW(m_exe, m_args.data(), NULL, NULL, FALSE,
	                              0, NULL, NULL, &si, &pi);
	if(created) {
		while(true) {
			if(m_pCrashInfo->exitLock.try_wait()) {
				break;
			}
			if(WaitForSingleObject(pi.hProcess, 100) != WAIT_TIMEOUT) {
				break;
			}
		}
		TerminateProcess(GetCurrentProcess(), 1);
		unregisterCrashHandlers();
		std::abort();
	}
	
	// Fallback: process the crash info in-process
	unregisterCrashHandlers();
	processCrash();
	
	std::abort();
}