Example #1
0
	static long __stdcall exception_filter(struct _EXCEPTION_POINTERS *info)
	{
		static const struct
		{
			DWORD code;
			const char *string;
		} exception_table[] =
		{
			{ EXCEPTION_ACCESS_VIOLATION,       "ACCESS VIOLATION" },
			{ EXCEPTION_DATATYPE_MISALIGNMENT,  "DATATYPE MISALIGNMENT" },
			{ EXCEPTION_BREAKPOINT,             "BREAKPOINT" },
			{ EXCEPTION_SINGLE_STEP,            "SINGLE STEP" },
			{ EXCEPTION_ARRAY_BOUNDS_EXCEEDED,  "ARRAY BOUNDS EXCEEDED" },
			{ EXCEPTION_FLT_DENORMAL_OPERAND,   "FLOAT DENORMAL OPERAND" },
			{ EXCEPTION_FLT_DIVIDE_BY_ZERO,     "FLOAT DIVIDE BY ZERO" },
			{ EXCEPTION_FLT_INEXACT_RESULT,     "FLOAT INEXACT RESULT" },
			{ EXCEPTION_FLT_INVALID_OPERATION,  "FLOAT INVALID OPERATION" },
			{ EXCEPTION_FLT_OVERFLOW,           "FLOAT OVERFLOW" },
			{ EXCEPTION_FLT_STACK_CHECK,        "FLOAT STACK CHECK" },
			{ EXCEPTION_FLT_UNDERFLOW,          "FLOAT UNDERFLOW" },
			{ EXCEPTION_INT_DIVIDE_BY_ZERO,     "INTEGER DIVIDE BY ZERO" },
			{ EXCEPTION_INT_OVERFLOW,           "INTEGER OVERFLOW" },
			{ EXCEPTION_PRIV_INSTRUCTION,       "PRIVILEGED INSTRUCTION" },
			{ EXCEPTION_IN_PAGE_ERROR,          "IN PAGE ERROR" },
			{ EXCEPTION_ILLEGAL_INSTRUCTION,    "ILLEGAL INSTRUCTION" },
			{ EXCEPTION_NONCONTINUABLE_EXCEPTION,"NONCONTINUABLE EXCEPTION" },
			{ EXCEPTION_STACK_OVERFLOW,         "STACK OVERFLOW" },
			{ EXCEPTION_INVALID_DISPOSITION,    "INVALID DISPOSITION" },
			{ EXCEPTION_GUARD_PAGE,             "GUARD PAGE VIOLATION" },
			{ EXCEPTION_INVALID_HANDLE,         "INVALID HANDLE" },
			{ 0,                                "UNKNOWN EXCEPTION" }
		};
		static int already_hit = 0;
		int i;

		// if we're hitting this recursively, just exit
		if (already_hit)
			return EXCEPTION_CONTINUE_SEARCH;
		already_hit = 1;

		// flush any debugging traces that were live
		debugger_flush_all_traces_on_abnormal_exit();

		// find our man
		for (i = 0; exception_table[i].code != 0; i++)
			if (info->ExceptionRecord->ExceptionCode == exception_table[i].code)
				break;

		// print the exception type and address
		fprintf(stderr, "\n-----------------------------------------------------\n");

		auto diagnostics = downcast<diagnostics_win32 *>(get_instance());

		fprintf(stderr, "Exception at EIP=%p%s: %s\n", info->ExceptionRecord->ExceptionAddress,
			diagnostics->m_symbols->symbol_for_address((FPTR)info->ExceptionRecord->ExceptionAddress), exception_table[i].string);

		// for access violations, print more info
		if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
			fprintf(stderr, "While attempting to %s memory at %p\n",
				info->ExceptionRecord->ExceptionInformation[0] ? "write" : "read",
				(void *)info->ExceptionRecord->ExceptionInformation[1]);

		// print the state of the CPU
		fprintf(stderr, "-----------------------------------------------------\n");
#ifdef PTR64
		fprintf(stderr, "RAX=%p RBX=%p RCX=%p RDX=%p\n",
			(void *)info->ContextRecord->Rax,
			(void *)info->ContextRecord->Rbx,
			(void *)info->ContextRecord->Rcx,
			(void *)info->ContextRecord->Rdx);
		fprintf(stderr, "RSI=%p RDI=%p RBP=%p RSP=%p\n",
			(void *)info->ContextRecord->Rsi,
			(void *)info->ContextRecord->Rdi,
			(void *)info->ContextRecord->Rbp,
			(void *)info->ContextRecord->Rsp);
		fprintf(stderr, " R8=%p  R9=%p R10=%p R11=%p\n",
			(void *)info->ContextRecord->R8,
			(void *)info->ContextRecord->R9,
			(void *)info->ContextRecord->R10,
			(void *)info->ContextRecord->R11);
		fprintf(stderr, "R12=%p R13=%p R14=%p R15=%p\n",
			(void *)info->ContextRecord->R12,
			(void *)info->ContextRecord->R13,
			(void *)info->ContextRecord->R14,
			(void *)info->ContextRecord->R15);
#else
		fprintf(stderr, "EAX=%p EBX=%p ECX=%p EDX=%p\n",
			(void *)info->ContextRecord->Eax,
			(void *)info->ContextRecord->Ebx,
			(void *)info->ContextRecord->Ecx,
			(void *)info->ContextRecord->Edx);
		fprintf(stderr, "ESI=%p EDI=%p EBP=%p ESP=%p\n",
			(void *)info->ContextRecord->Esi,
			(void *)info->ContextRecord->Edi,
			(void *)info->ContextRecord->Ebp,
			(void *)info->ContextRecord->Esp);
#endif

		// reprint the actual exception address
		fprintf(stderr, "-----------------------------------------------------\n");
		fprintf(stderr, "Stack crawl:\n");
		diagnostics->print_stacktrace(info->ContextRecord, GetCurrentThread());

		// flush stderr, so the data is actually written when output is being redirected
		fflush(stderr);

		// exit
		return EXCEPTION_CONTINUE_SEARCH;
	}
Example #2
0
static LONG CALLBACK exception_filter(struct _EXCEPTION_POINTERS *info)
{
	static const struct
	{
		DWORD code;
		const char *string;
	} exception_table[] =
	{
		{ EXCEPTION_ACCESS_VIOLATION,		"ACCESS VIOLATION" },
		{ EXCEPTION_DATATYPE_MISALIGNMENT,	"DATATYPE MISALIGNMENT" },
		{ EXCEPTION_BREAKPOINT, 			"BREAKPOINT" },
		{ EXCEPTION_SINGLE_STEP,			"SINGLE STEP" },
		{ EXCEPTION_ARRAY_BOUNDS_EXCEEDED,	"ARRAY BOUNDS EXCEEDED" },
		{ EXCEPTION_FLT_DENORMAL_OPERAND,	"FLOAT DENORMAL OPERAND" },
		{ EXCEPTION_FLT_DIVIDE_BY_ZERO,		"FLOAT DIVIDE BY ZERO" },
		{ EXCEPTION_FLT_INEXACT_RESULT,		"FLOAT INEXACT RESULT" },
		{ EXCEPTION_FLT_INVALID_OPERATION,	"FLOAT INVALID OPERATION" },
		{ EXCEPTION_FLT_OVERFLOW,			"FLOAT OVERFLOW" },
		{ EXCEPTION_FLT_STACK_CHECK,		"FLOAT STACK CHECK" },
		{ EXCEPTION_FLT_UNDERFLOW,			"FLOAT UNDERFLOW" },
		{ EXCEPTION_INT_DIVIDE_BY_ZERO,		"INTEGER DIVIDE BY ZERO" },
		{ EXCEPTION_INT_OVERFLOW,			"INTEGER OVERFLOW" },
		{ EXCEPTION_PRIV_INSTRUCTION,		"PRIVILEGED INSTRUCTION" },
		{ EXCEPTION_IN_PAGE_ERROR,			"IN PAGE ERROR" },
		{ EXCEPTION_ILLEGAL_INSTRUCTION,	"ILLEGAL INSTRUCTION" },
		{ EXCEPTION_NONCONTINUABLE_EXCEPTION,"NONCONTINUABLE EXCEPTION" },
		{ EXCEPTION_STACK_OVERFLOW, 		"STACK OVERFLOW" },
		{ EXCEPTION_INVALID_DISPOSITION,	"INVALID DISPOSITION" },
		{ EXCEPTION_GUARD_PAGE, 			"GUARD PAGE VIOLATION" },
		{ EXCEPTION_INVALID_HANDLE, 		"INVALID HANDLE" },
		{ 0,								"UNKNOWN EXCEPTION" }
	};
	static int already_hit = 0;
	int i;

	// if we're hitting this recursively, just exit
	if (already_hit)
		return EXCEPTION_CONTINUE_SEARCH;
	already_hit = 1;

	// flush any debugging traces that were live
	debugger_flush_all_traces_on_abnormal_exit();

	// find our man
	for (i = 0; exception_table[i].code != 0; i++)
		if (info->ExceptionRecord->ExceptionCode == exception_table[i].code)
			break;

	// print the exception type and address
	fprintf(stderr, "\n-----------------------------------------------------\n");
	fprintf(stderr, "Exception at EIP=%p%s: %s\n", info->ExceptionRecord->ExceptionAddress,
			lookup_symbol((FPTR)info->ExceptionRecord->ExceptionAddress), exception_table[i].string);

	// for access violations, print more info
	if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
		fprintf(stderr, "While attempting to %s memory at %p\n",
				info->ExceptionRecord->ExceptionInformation[0] ? "write" : "read",
				(void *)info->ExceptionRecord->ExceptionInformation[1]);

	// print the state of the CPU
	fprintf(stderr, "-----------------------------------------------------\n");
#ifdef PTR64
	fprintf(stderr, "RAX=%p RBX=%p RCX=%p RDX=%p\n",
			(void *)info->ContextRecord->Rax,
			(void *)info->ContextRecord->Rbx,
			(void *)info->ContextRecord->Rcx,
			(void *)info->ContextRecord->Rdx);
	fprintf(stderr, "RSI=%p RDI=%p RBP=%p RSP=%p\n",
			(void *)info->ContextRecord->Rsi,
			(void *)info->ContextRecord->Rdi,
			(void *)info->ContextRecord->Rbp,
			(void *)info->ContextRecord->Rsp);
	fprintf(stderr, " R8=%p  R9=%p R10=%p R11=%p\n",
			(void *)info->ContextRecord->R8,
			(void *)info->ContextRecord->R9,
			(void *)info->ContextRecord->R10,
			(void *)info->ContextRecord->R11);
	fprintf(stderr, "R12=%p R13=%p R14=%p R15=%p\n",
			(void *)info->ContextRecord->R12,
			(void *)info->ContextRecord->R13,
			(void *)info->ContextRecord->R14,
			(void *)info->ContextRecord->R15);
#else
	fprintf(stderr, "EAX=%p EBX=%p ECX=%p EDX=%p\n",
			(void *)info->ContextRecord->Eax,
			(void *)info->ContextRecord->Ebx,
			(void *)info->ContextRecord->Ecx,
			(void *)info->ContextRecord->Edx);
	fprintf(stderr, "ESI=%p EDI=%p EBP=%p ESP=%p\n",
			(void *)info->ContextRecord->Esi,
			(void *)info->ContextRecord->Edi,
			(void *)info->ContextRecord->Ebp,
			(void *)info->ContextRecord->Esp);
#endif

	if (image_nt_header != NULL &&
		stack_walk_64 != NULL &&
		sym_initialize != NULL &&
		sym_function_table_access_64 != NULL &&
		sym_get_module_base_64 != NULL &&
		sym_from_addr != NULL &&
		get_module_information != NULL)
	{
		CONTEXT context = *info->ContextRecord;
		STACKFRAME64 stackframe;

		// initialize the symbol lookup
		sym_initialize(GetCurrentProcess(), NULL, TRUE);

		// reprint the actual exception address
		fprintf(stderr, "-----------------------------------------------------\n");
		fprintf(stderr, "Stack crawl:\n");

		memset(&stackframe, 0, sizeof(stackframe));
#ifdef PTR64
		stackframe.AddrPC.Offset = context.Rip;
		stackframe.AddrFrame.Offset = context.Rsp;
		stackframe.AddrStack.Offset = context.Rsp;
#else
		stackframe.AddrPC.Offset = context.Eip;
		stackframe.AddrFrame.Offset = context.Ebp;
		stackframe.AddrStack.Offset = context.Esp;
#endif
		stackframe.AddrPC.Mode = AddrModeFlat;
		stackframe.AddrFrame.Mode = AddrModeFlat;
		stackframe.AddrStack.Mode = AddrModeFlat;

		while (stack_walk_64(
#ifdef PTR64
				IMAGE_FILE_MACHINE_AMD64,
#else
				IMAGE_FILE_MACHINE_I386,
#endif
				GetCurrentProcess(),
				GetCurrentThread(),
				&stackframe,
				&context,
				NULL,
				sym_function_table_access_64,
				sym_get_module_base_64,
				NULL))
		{
			fprintf(stderr, "  %p: %p%s\n", (void *)stackframe.AddrFrame.Offset, (void *)stackframe.AddrPC.Offset, lookup_symbol((FPTR)stackframe.AddrPC.Offset));
		}
	}

	// exit
	return EXCEPTION_CONTINUE_SEARCH;
}