Esempio n. 1
0
static void posixExceptionHandler(int signum)
#endif
{
	static sig_atomic_t allreadyRunning = 0;
	// XXXXXX will be converted into random characters by mkstemp(3)
	static const char gdmpPath[] = "/tmp/warzone2100.gdmp-XXXXXX";
	char dumpFilename[sizeof(gdmpPath)];
	int dumpFile;
	const char *signal;
# if defined(__GLIBC__)
	void * btBuffer[MAX_BACKTRACE] = {NULL};
	uint32_t btSize = backtrace(btBuffer, MAX_BACKTRACE);
# endif

	if (allreadyRunning)
		raise(signum);
	allreadyRunning = 1;

	sstrcpy(dumpFilename, gdmpPath);

	dumpFile = mkstemp(dumpFilename);

	if (dumpFile == -1)
	{
		printf("Failed to create dump file '%s'", dumpFilename);
		return;
	}

	// Dump a generic info header
	dbgDumpHeader(dumpFile);

#ifdef SA_SIGINFO
	write(dumpFile, "Dump caused by signal: ", strlen("Dump caused by signal: "));

	signal = wz_strsignal(siginfo->si_signo, siginfo->si_code);
	write(dumpFile, signal, strlen(signal));
	write(dumpFile, "\n\n", 2);
#endif

	dbgDumpLog(dumpFile); // dump out the last several log calls

# if defined(__GLIBC__)
	// Dump raw backtrace in case GDB is not available or fails
	write(dumpFile, "GLIBC raw backtrace:\n", strlen("GLIBC raw backtrace:\n"));
	backtrace_symbols_fd(btBuffer, btSize, dumpFile);
	write(dumpFile, "\n", 1);
# else
	write(dumpFile, "GLIBC not available, no raw backtrace dumped\n\n",
		  strlen("GLIBC not available, no raw backtrace dumped\n\n"));
# endif


	// Make sure everything is written before letting GDB write to it
	fsync(dumpFile);

	// Use 'gdb' to provide an "extended" backtrace
#ifdef SA_SIGINFO
	gdbExtendedBacktrace(dumpFile, (ucontext_t*)sigcontext);
#else
	gdbExtendedBacktrace(dumpFile);
#endif

	printf("Saved dump file to '%s'\n"
	       "If you create a bugreport regarding this crash, please include this file.\n", dumpFilename);
	close(dumpFile);


	sigaction(signum, &oldAction[signum], NULL);
	raise(signum);
}
Esempio n. 2
0
static
void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo)
{
	PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
	TCHAR szModule[MAX_PATH];
	HMODULE hModule;
	PCONTEXT pContext;

	// Start out with a banner
	rprintf(_T("-------------------\r\n\r\n"));

	{
		const TCHAR *lpDayOfWeek[] = {
			_T("Sunday"),
			_T("Monday"),
			_T("Tuesday"),
			_T("Wednesday"),
			_T("Thursday"),
			_T("Friday"),
			_T("Saturday")
		};
		const TCHAR *lpMonth[] = {
			NULL,
			_T("January"),
			_T("February"),
			_T("March"),
			_T("April"),
			_T("May"),
			_T("June"),
			_T("July"),
			_T("August"),
			_T("September"),
			_T("October"),
			_T("November"),
			_T("December")
		};
		SYSTEMTIME SystemTime;

		GetLocalTime(&SystemTime);
		rprintf(_T("Error occured on %s, %s %i, %i at %02i:%02i:%02i.\r\n\r\n"),
			lpDayOfWeek[SystemTime.wDayOfWeek],
			lpMonth[SystemTime.wMonth],
			SystemTime.wDay,
			SystemTime.wYear,
			SystemTime.wHour,
			SystemTime.wMinute,
			SystemTime.wSecond
		);
	}

	// Dump a generic info header
	dbgDumpHeader(hReportFile);

	// First print information about the type of fault
	rprintf(_T("\r\n%s caused "),  GetModuleFileName(NULL, szModule, MAX_PATH) ? szModule : "Application");
	switch(pExceptionRecord->ExceptionCode)
	{
		case EXCEPTION_ACCESS_VIOLATION:
			rprintf(_T("an Access Violation"));
			break;

		case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
			rprintf(_T("an Array Bound Exceeded"));
			break;

		case EXCEPTION_BREAKPOINT:
			rprintf(_T("a Breakpoint"));
			break;

		case EXCEPTION_DATATYPE_MISALIGNMENT:
			rprintf(_T("a Datatype Misalignment"));
			break;

		case EXCEPTION_FLT_DENORMAL_OPERAND:
			rprintf(_T("a Float Denormal Operand"));
			break;

		case EXCEPTION_FLT_DIVIDE_BY_ZERO:
			rprintf(_T("a Float Divide By Zero"));
			break;

		case EXCEPTION_FLT_INEXACT_RESULT:
			rprintf(_T("a Float Inexact Result"));
			break;

		case EXCEPTION_FLT_INVALID_OPERATION:
			rprintf(_T("a Float Invalid Operation"));
			break;

		case EXCEPTION_FLT_OVERFLOW:
			rprintf(_T("a Float Overflow"));
			break;

		case EXCEPTION_FLT_STACK_CHECK:
			rprintf(_T("a Float Stack Check"));
			break;

		case EXCEPTION_FLT_UNDERFLOW:
			rprintf(_T("a Float Underflow"));
			break;

		case EXCEPTION_GUARD_PAGE:
			rprintf(_T("a Guard Page"));
			break;

		case EXCEPTION_ILLEGAL_INSTRUCTION:
			rprintf(_T("an Illegal Instruction"));
			break;

		case EXCEPTION_IN_PAGE_ERROR:
			rprintf(_T("an In Page Error"));
			break;

		case EXCEPTION_INT_DIVIDE_BY_ZERO:
			rprintf(_T("an Integer Divide By Zero"));
			break;

		case EXCEPTION_INT_OVERFLOW:
			rprintf(_T("an Integer Overflow"));
			break;

		case EXCEPTION_INVALID_DISPOSITION:
			rprintf(_T("an Invalid Disposition"));
			break;

		case EXCEPTION_INVALID_HANDLE:
			rprintf(_T("an Invalid Handle"));
			break;

		case EXCEPTION_NONCONTINUABLE_EXCEPTION:
			rprintf(_T("a Noncontinuable Exception"));
			break;

		case EXCEPTION_PRIV_INSTRUCTION:
			rprintf(_T("a Privileged Instruction"));
			break;

		case EXCEPTION_SINGLE_STEP:
			rprintf(_T("a Single Step"));
			break;

		case EXCEPTION_STACK_OVERFLOW:
			rprintf(_T("a Stack Overflow"));
			break;

		case DBG_CONTROL_C:
			rprintf(_T("a Control+C"));
			break;

		case DBG_CONTROL_BREAK:
			rprintf(_T("a Control+Break"));
			break;

		case DBG_TERMINATE_THREAD:
			rprintf(_T("a Terminate Thread"));
			break;

		case DBG_TERMINATE_PROCESS:
			rprintf(_T("a Terminate Process"));
			break;

		case RPC_S_UNKNOWN_IF:
			rprintf(_T("an Unknown Interface"));
			break;

		case RPC_S_SERVER_UNAVAILABLE:
			rprintf(_T("a Server Unavailable"));
			break;

		default:
			/*
			static TCHAR szBuffer[512] = { 0 };

			// If not one of the "known" exceptions, try to get the string
			// from NTDLL.DLL's message table.

			FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
							GetModuleHandle(_T("NTDLL.DLL")),
							dwCode, 0, szBuffer, sizeof(szBuffer), 0);
			*/

			rprintf(_T("an Unknown [0x%lX] Exception"), pExceptionRecord->ExceptionCode);
			break;
	}

	// Now print information about where the fault occured
	rprintf(_T(" at location %08x"), (DWORD) pExceptionRecord->ExceptionAddress);
	if((hModule = (HMODULE) GetModuleBase((DWORD) pExceptionRecord->ExceptionAddress)) && GetModuleFileName(hModule, szModule, sizeof(szModule)))
		rprintf(_T(" in module %s"), szModule);

	// If the exception was an access violation, print out some additional information, to the error log and the debugger.
	if(pExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && pExceptionRecord->NumberParameters >= 2)
		rprintf(" %s location %08x", pExceptionRecord->ExceptionInformation[0] ? "Writing to" : "Reading from", pExceptionRecord->ExceptionInformation[1]);

	rprintf(".\r\n\r\n");

	dbgDumpLog(hReportFile);

	pContext = pExceptionInfo->ContextRecord;

	#ifdef _M_IX86	// Intel Only!

	// Show the registers
	rprintf(_T("Registers:\r\n"));
	if(pContext->ContextFlags & CONTEXT_INTEGER)
		rprintf(
			_T("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\r\n"),
			pContext->Eax,
			pContext->Ebx,
			pContext->Ecx,
			pContext->Edx,
			pContext->Esi,
			pContext->Edi
		);
	if(pContext->ContextFlags & CONTEXT_CONTROL)
		rprintf(
			_T("eip=%08lx esp=%08lx ebp=%08lx iopl=%1lx %s %s %s %s %s %s %s %s %s %s\r\n"),
			pContext->Eip,
			pContext->Esp,
			pContext->Ebp,
			(pContext->EFlags >> 12) & 3,	//  IOPL level value
			pContext->EFlags & 0x00100000 ? "vip" : "   ",	//  VIP (virtual interrupt pending)
			pContext->EFlags & 0x00080000 ? "vif" : "   ",	//  VIF (virtual interrupt flag)
			pContext->EFlags & 0x00000800 ? "ov" : "nv",	//  VIF (virtual interrupt flag)
			pContext->EFlags & 0x00000400 ? "dn" : "up",	//  OF (overflow flag)
			pContext->EFlags & 0x00000200 ? "ei" : "di",	//  IF (interrupt enable flag)
			pContext->EFlags & 0x00000080 ? "ng" : "pl",	//  SF (sign flag)
			pContext->EFlags & 0x00000040 ? "zr" : "nz",	//  ZF (zero flag)
			pContext->EFlags & 0x00000010 ? "ac" : "na",	//  AF (aux carry flag)
			pContext->EFlags & 0x00000004 ? "po" : "pe",	//  PF (parity flag)
			pContext->EFlags & 0x00000001 ? "cy" : "nc"	//  CF (carry flag)
		);
	if(pContext->ContextFlags & CONTEXT_SEGMENTS)
	{
		rprintf(
			_T("cs=%04lx  ss=%04lx  ds=%04lx  es=%04lx  fs=%04lx  gs=%04lx"),
			pContext->SegCs,
			pContext->SegSs,
			pContext->SegDs,
			pContext->SegEs,
			pContext->SegFs,
			pContext->SegGs,
			pContext->EFlags
		);
		if(pContext->ContextFlags & CONTEXT_CONTROL)
			rprintf(
				_T("             efl=%08lx"),
				pContext->EFlags
			);
	}
	else
		if(pContext->ContextFlags & CONTEXT_CONTROL)
			rprintf(
				_T("                                                                       efl=%08lx"),
				pContext->EFlags
			);
	rprintf(_T("\r\n\r\n"));

	#endif
	// FIXME: We *never* return from the below call!
	StackBackTrace(GetCurrentProcess(), GetCurrentThread(), pContext);

	rprintf(_T("\r\n\r\n"));
}