void CrashHandlerPOSIX::handleCrash(int signal, int code) {
	
	// Remove crash handlers so we don't end in an infinite crash loop
	removeCrashHandlers(m_pPreviousCrashHandlers);
	
	// Run the callbacks
	for(std::vector<CrashHandler::CrashCallback>::iterator it = m_crashCallbacks.begin();
	    it != m_crashCallbacks.end(); ++it) {
		(*it)();
	}
	
	m_pCrashInfo->signal = signal;
	m_pCrashInfo->code = code;
	
	// Store the backtrace in the shared crash info
	#ifdef HAVE_BACKTRACE
		backtrace(m_pCrashInfo->backtrace, ARRAY_SIZE(m_pCrashInfo->backtrace));
	#endif
	
	m_pCrashInfo->crashBrokerLock.post();
	
	while(true) {
		// Busy wait so we don't enter any additional stack frames and keep the backtrace clean.
	}
}
void CrashHandlerPOSIX::unregisterCrashHandlers() {
	
	unregisterThreadCrashHandlers();
	
	removeCrashHandlers(m_pPreviousCrashHandlers);
	
	delete m_pPreviousCrashHandlers;
	m_pPreviousCrashHandlers = 0;
}
void CrashHandlerPOSIX::handleCrash(int signal, void * info, void * context) {
	
	// Remove crash handlers so we don't end in an infinite crash loop
	removeCrashHandlers(m_pPreviousCrashHandlers);
	
	// Run the callbacks
	for(std::vector<CrashHandler::CrashCallback>::iterator it = m_crashCallbacks.begin();
	    it != m_crashCallbacks.end(); ++it) {
		(*it)();
	}
	
	m_pCrashInfo->signal = signal;
	
	#if ARX_HAVE_SIGACTION
	if(info) {
		siginfo_t * siginfo = reinterpret_cast<siginfo_t *>(info);
		m_pCrashInfo->code = siginfo->si_code;
		#if defined(SIGILL) || defined(SIGFPE)
		if(signal == SIGILL || signal == SIGFPE) {
			m_pCrashInfo->address = u64(siginfo->si_addr);
			m_pCrashInfo->hasAddress = true;
		}
		#endif
		#if defined(SIGSEGV) && defined(SIGBUS)
		if(signal == SIGSEGV || signal == SIGBUS) {
			m_pCrashInfo->memory = u64(siginfo->si_addr);
			m_pCrashInfo->hasMemory = true;
		}
		#endif
	}
	#endif
	
	#if ARX_HAVE_SIGACTION && ARX_PLATFORM == ARX_PLATFORM_LINUX
	if(context) {
		ucontext_t * ctx = reinterpret_cast<ucontext_t *>(context);
		#if ARX_ARCH == ARX_ARCH_X86 && defined(REG_EIP)
		m_pCrashInfo->address = ctx->uc_mcontext.gregs[REG_EIP];
		m_pCrashInfo->hasAddress = true;
		m_pCrashInfo->stack = ctx->uc_mcontext.gregs[REG_ESP];
		m_pCrashInfo->hasStack = true;
		m_pCrashInfo->frame = ctx->uc_mcontext.gregs[REG_EBP];
		m_pCrashInfo->hasFrame = true;
		#elif ARX_ARCH == ARX_ARCH_X86_64 && defined(REG_RIP)
		m_pCrashInfo->address = ctx->uc_mcontext.gregs[REG_RIP];
		m_pCrashInfo->hasAddress = true;
		m_pCrashInfo->stack = ctx->uc_mcontext.gregs[REG_RSP];
		m_pCrashInfo->hasStack = true;
		#elif ARX_ARCH == ARX_ARCH_ARM
		m_pCrashInfo->address =  ctx->uc_mcontext.arm_pc;
		m_pCrashInfo->hasAddress = true;
		m_pCrashInfo->stack =  ctx->uc_mcontext.arm_sp;
		m_pCrashInfo->hasStack = true;
		m_pCrashInfo->frame = ctx->uc_mcontext.arm_fp;
		m_pCrashInfo->hasFrame = true;
		#else
		ARX_UNUSED(ctx);
		#endif
	}
	#else
	ARX_UNUSED(context);
	#endif
	
	// Store the backtrace in the shared crash info
	#if ARX_HAVE_BACKTRACE
	backtrace(m_pCrashInfo->backtrace, boost::size(m_pCrashInfo->backtrace));
	#endif
	
	// Change directory core dumps are written to
	if(m_pCrashInfo->crashReportFolder[0] != '\0') {
		#if ARX_HAVE_CHDIR
		if(chdir(m_pCrashInfo->crashReportFolder) == 0) {
			// Shut up GCC, we don't care
		}
		#endif
	}
	
	// Try to spawn a sub-process to process the crash info
	// Using fork() in a signal handler is bad, but we are already crashing anyway
	pid_t processor = fork();
	if(processor > 0) {
		while(true) {
			if(m_pCrashInfo->exitLock.try_wait()) {
				break;
			}
			#if ARX_HAVE_WAITPID
			if(waitpid(processor, NULL, WNOHANG) != 0) {
				break;
			}
			#endif
			#if ARX_HAVE_NANOSLEEP
			timespec t;
			t.tv_sec = 0;
			t.tv_nsec = 100 * 1000;
			nanosleep(&t, NULL);
			#endif
		}
		// Exit if the crash reporter failed
		kill(getpid(), SIGKILL);
		std::abort();
	}
	#ifdef ARX_HAVE_EXECVP
	char argument[256];
	strcpy(argument, "--crashinfo=");
	strcat(argument, m_SharedMemoryName.c_str());
	const char * args[] = { m_executable.string().c_str(), argument, NULL };
	execvp(m_executable.string().c_str(), const_cast<char **>(args));
	#endif
	
	// Fallback: process the crash info in-process
	processCrash();
	
	std::abort();
}