Пример #1
0
void NORETURN sm_crash( std::string const &reason )
{
#if ( defined(_WINDOWS) && defined(CRASH_HANDLER) ) || defined(MACOSX) || defined(_XDBG)
	/* If we're being debugged, throw a debug break so it'll suspend the process. */
	if( IsDebuggerPresent() )
	{
		DebugBreak();
		for(;;); /* don't return */
	}
#endif

#if defined(CRASH_HANDLER)
	CrashHandler::ForceCrash( reason );
#else
	*(char*)0=0;

	/* This isn't actually reached.  We just do this to convince the compiler that the
	 * function really doesn't return. */
	for(;;);
#endif

#if defined(_WINDOWS)
	/* Do something after the above, so the call/return isn't optimized to a jmp; that
	 * way, this function will appear in backtrace stack traces. */
#if defined(_MSC_VER)
	_asm nop;
#elif defined(__GNUC__) // MinGW or similar
	asm("nop");
#endif
#else
	_exit( 1 );
#endif
}
Пример #2
0
/* This is no longer actually implemented by throwing an exception, but it acts
 * the same way to code in practice. */
void RageException::Throw( const char *sFmt, ... )
{
	va_list	va;
	va_start( va, sFmt );
	RString error = vssprintf( sFmt, va );
	va_end( va );

	RString msg = ssprintf(
		"\n"
		"//////////////////////////////////////////////////////\n"
		"Exception: %s\n"
		"//////////////////////////////////////////////////////\n",
		error.c_str() );
	if( LOG )
	{
		LOG->Trace( "%s", msg.c_str() );
		LOG->Flush();
	}
	else
	{
		puts( msg );
		fflush( stdout );
	}

#if (defined(WINDOWS) && defined(DEBUG)) || defined(_XDBG) || defined(MACOSX)
	if( IsDebuggerPresent() )
		DebugBreak();
#endif

	ASSERT_M( g_HandlerThreadID == RageThread::GetInvalidThreadID() || g_HandlerThreadID == RageThread::GetCurrentThreadID(),
		  ssprintf("RageException::Throw() on another thread: %s", error.c_str()) );
	if( g_CleanupHandler != NULL )
		g_CleanupHandler( error );

	exit(1);
}