예제 #1
0
void WriteExceptionInfo(FILE* f, EXCEPTION_POINTERS* exceptionPtrs)
{
    WriteProcessName(f);
    fprintf(f, "\n");

    fprintf(f, "Reason: 0x%X - %s", exceptionPtrs->ExceptionRecord->ExceptionCode,
            GetExceptionString(exceptionPtrs->ExceptionRecord->ExceptionCode));
    fprintf(f, " at %04X:%p\n", exceptionPtrs->ContextRecord->SegCs,
            exceptionPtrs->ExceptionRecord->ExceptionAddress);

    if (exceptionPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
    {
        fprintf(f, "Attempt to %s 0x%08X\n", 
            (exceptionPtrs->ExceptionRecord->ExceptionInformation[0] == 1 ? 
            "write to" : "read from"), exceptionPtrs->ExceptionRecord->ExceptionInformation[1]);
    }
    const DWORD threadId = ::GetCurrentThreadId();
    fprintf(f, "Thread ID: 0x%X [%d]\n\n", threadId, threadId);
}
예제 #2
0
bool ErrorReport::GetMiscCrashInfo() {
	
	// Get crash time
	m_CrashDateTime = QDateTime::currentDateTime();
	
	m_ProcessArchitecture = ARX_ARCH_NAME;
	
	m_OSName = QString::fromUtf8(platform::getOSName().c_str());
	m_OSArchitecture = QString::fromUtf8(platform::getOSArchitecture().c_str());
	m_OSDistribution = QString::fromUtf8(platform::getOSDistribution().c_str());
	
#if ARX_PLATFORM == ARX_PLATFORM_WIN32
	
	// Open parent process handle
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pCrashInfo->processId);
	if(hProcess != NULL)
	{
		// Get memory usage info
		PROCESS_MEMORY_COUNTERS meminfo;
		BOOL bGetMemInfo = GetProcessMemoryInfo(hProcess, &meminfo, sizeof(PROCESS_MEMORY_COUNTERS));
		if(bGetMemInfo)
			m_ProcessMemoryUsage = meminfo.WorkingSetSize;

		// Determine the period of time the process is working.
		FILETIME CreationTime, ExitTime, KernelTime, UserTime;
		BOOL bGetTimes = GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime);
		if(bGetTimes)
		{
			SYSTEMTIME AppStartTime;
			FileTimeToSystemTime(&CreationTime, &AppStartTime);

			SYSTEMTIME CurTime;
			GetSystemTime(&CurTime);
			ULONG64 uCurTime = ConvertSystemTimeToULONG64(CurTime);
			ULONG64 uStartTime = ConvertSystemTimeToULONG64(AppStartTime);

			// Check that the application works for at least one minute before crash.
			// This might help to avoid cyclic error report generation when the applciation
			// crashes on startup.
			m_RunningTimeSec = (double)(uCurTime-uStartTime)*10E-08;
		}
	}
	else
	{
		m_DetailedError = QString("Unable to obtain an handle to the crashed process (Error %1).").arg(QString::number(GetLastError()));
		return false;
	}
	
	if(m_pCrashInfo->exceptionCode != 0)
	{
		QString exceptionStr = GetExceptionString(m_pCrashInfo->exceptionCode).c_str();
		if(!exceptionStr.isEmpty())
		{
			m_ReportDescription += "\nException code:\n  ";
			m_ReportDescription += exceptionStr;
			m_ReportDescription += "\n";
		}
	}

	std::string callStack, callstackTop;
	u32 callstackCrc;

	bool bCallstack = GetCallStackInfo(hProcess, m_pCrashInfo->threadHandle, &m_pCrashInfo->contextRecord, callStack, callstackTop, callstackCrc);
	if(!bCallstack) 
	{
		m_DetailedError = "A failure occured when obtaining information regarding the callstack.";
		return false;
	}
	
	m_ReportUniqueID = QString("[%1]").arg(QString::number(callstackCrc, 16).toUpper());
	
	m_ReportDescription = m_pCrashInfo->detailedCrashInfo;
	m_ReportDescription += "\nCallstack:\n";
	m_ReportDescription += callStack.c_str();
	m_ReportTitle = QString("%1 %2").arg(m_ReportUniqueID, callstackTop.c_str());

	QString registers(GetRegisters(&m_pCrashInfo->contextRecord).c_str());
	if(!registers.isEmpty())
	{
		m_ReportDescription += "\nRegisters:\n";
		m_ReportDescription += registers;
	}
	
	CloseHandle(hProcess);
	
	m_ReportDescriptionText = m_ReportDescription;
	
#else // ARX_PLATFORM != ARX_PLATFORM_WIN32
	
	getResourceUsage(m_pCrashInfo->processId, m_ProcessMemoryUsage, m_RunningTimeSec);
	
#endif

	return true;
}