//-----------------------------------------------------------------------------
// Purpose: Warning/Msg call back through this API
// Input  : type - 
//			*pMsg - 
// Output : SpewRetval_t
//-----------------------------------------------------------------------------
SpewRetval_t SpewFunc( SpewType_t type, const char *pMsg )
{
	if ( Plat_IsInDebugSession() )
	{
		OutputDebugString( pMsg );
		if ( type == SPEW_ASSERT )
			return SPEW_DEBUGGER;
	}
	return SPEW_CONTINUE;
}
Beispiel #2
0
void _ExitOnFatalAssert( const tchar* pFile, int line )
{
	_SpewMessage( _T("Fatal assert failed: %s, line %d.  Application exiting.\n"), pFile, line );

	// only write out minidumps if we're not in the debugger
	if ( !Plat_IsInDebugSession() )
	{
		WriteMiniDump();
	}

	DevMsg( 1, _T("_ExitOnFatalAssert\n") );
	exit( EXIT_FAILURE );
}
Beispiel #3
0
int CWorkerThread::WaitForReply( unsigned timeout, WaitFunc_t pfnWait )
{
	if (!pfnWait)
	{
		pfnWait = DefaultWaitFunc;
	}

	HANDLE waits[] =
	{
		GetThreadHandle(),
		m_EventComplete
	};

	unsigned result;
	bool bInDebugger = Plat_IsInDebugSession();

	do
	{
		// Make sure the thread handle hasn't been closed
		if ( !GetThreadHandle() )
		{
			result = WAIT_OBJECT_0 + 1;
			break;
		}

		result = (*pfnWait)((sizeof(waits) / sizeof(waits[0])), waits, false,
			(timeout != TT_INFINITE) ? timeout : 30000);

		AssertMsg(timeout != TT_INFINITE || result != WAIT_TIMEOUT, "Possible hung thread, call to thread timed out");

	} while ( bInDebugger && ( timeout == TT_INFINITE && result == WAIT_TIMEOUT ) );

	if ( result != WAIT_OBJECT_0 + 1 )
	{
		if (result == WAIT_TIMEOUT)
			m_ReturnVal = WTCR_TIMEOUT;
		else if (result == WAIT_OBJECT_0)
		{
			DevMsg( 2, "Thread failed to respond, probably exited\n");
			m_EventSend.Reset();
			m_ReturnVal = WTCR_TIMEOUT;
		}
		else
		{
			m_EventSend.Reset();
			m_ReturnVal = WTCR_THREAD_GONE;
		}
	}

	return m_ReturnVal;
}
Beispiel #4
0
// Write a minidump file, unless running under the debugger in which case break
// into the debugger.
// The "int dummy" parameter is so that the callers can be unique so that the
// linker won't use its /opt:icf optimization to collapse them together. This
// makes reading the call stack easier.
void __cdecl WriteMiniDumpOrBreak( int dummy, const char *pchName )
{
	if ( Plat_IsInDebugSession() )
	{
		__debugbreak();
		// Continue at your peril...
	}
	else
	{
		WriteMiniDump( pchName );
		// Call Plat_ExitProcess so we don't continue in a bad state. 
		TerminateProcess(GetCurrentProcess(), 0);
	}
}
Beispiel #5
0
DBG_INTERFACE bool ShouldUseNewAssertDialog()
{
	static bool bMPIWorker = ( _tcsstr( Plat_GetCommandLine(), _T("-mpi_worker") ) != NULL );
	if ( bMPIWorker )
	{
		return false;
	}

#ifdef DBGFLAG_ASSERTDLG
	return true;		// always show an assert dialog
#else
	return Plat_IsInDebugSession();		// only show an assert dialog if the process is being debugged
#endif // DBGFLAG_ASSERTDLG
}
//-----------------------------------------------------------------------------
// Purpose: Catches and writes out any exception throw by the specified function
//-----------------------------------------------------------------------------
void CatchAndWriteMiniDump( FnWMain pfn, int argc, tchar *argv[] )
{
	if ( Plat_IsInDebugSession() )
	{
		// don't mask exceptions when running in the debugger
		pfn( argc, argv );
	}
	else
	{
		try
		{
			_set_se_translator( g_pfnWriteMiniDump );
			pfn( argc, argv );
		}
		catch (...)
		{
			g_bInException = true;
			DMsg( "console", 1, _T("Fatal exception caught, minidump written\n") );
			// handle everything and just quit, we've already written out our minidump
		}
	}
}
SpewRetval_t CmdLib_SpewOutputFunc( SpewType_t type, char const *pMsg )
{
	// Hopefully two threads won't call this simultaneously right at the start!
	if ( !g_bSpewCSInitted )
	{
		InitializeCriticalSection( &g_SpewCS );
		g_bSpewCSInitted = true;
	}

	WORD old;
	SpewRetval_t retVal;
	
	EnterCriticalSection( &g_SpewCS );
	{
		if (( type == SPEW_MESSAGE ) || (type == SPEW_LOG ))
		{
			Color c = GetSpewOutputColor();
			if ( c.r() != 255 || c.g() != 255 || c.b() != 255 )
			{
				// custom color
				old = SetConsoleTextColor( c.r(), c.g(), c.b(), c.a() );
			}
			else
			{
				old = SetConsoleTextColor( 1, 1, 1, 0 );
			}
			retVal = SPEW_CONTINUE;
		}
		else if( type == SPEW_WARNING )
		{
			old = SetConsoleTextColor( 1, 1, 0, 1 );
			retVal = SPEW_CONTINUE;
		}
		else if( type == SPEW_ASSERT )
		{
			old = SetConsoleTextColor( 1, 0, 0, 1 );
			retVal = SPEW_DEBUGGER;

#ifdef MPI
			// VMPI workers don't want to bring up dialogs and suchlike.
			// They need to have a special function installed to handle
			// the exceptions and write the minidumps.
			// Install the function after VMPI_Init with a call:
			// SetupToolsMinidumpHandler( VMPI_ExceptionFilter );
			if ( g_bUseMPI && !g_bMPIMaster && !Plat_IsInDebugSession() )
			{
				// Generating an exception and letting the
				// installed handler handle it
				::RaiseException
					(
					0,							// dwExceptionCode
					EXCEPTION_NONCONTINUABLE,	// dwExceptionFlags
					0,							// nNumberOfArguments,
					NULL						// const ULONG_PTR* lpArguments
					);

					// Never get here (non-continuable exception)
				
				VMPI_HandleCrash( pMsg, NULL, true );
				exit( 0 );
			}
#endif
		}
		else if( type == SPEW_ERROR )
		{
			old = SetConsoleTextColor( 1, 0, 0, 1 );
			retVal = SPEW_ABORT; // doesn't matter.. we exit below so we can return an errorlevel (which dbg.dll doesn't do).
		}
		else
		{
			old = SetConsoleTextColor( 1, 1, 1, 1 );
			retVal = SPEW_CONTINUE;
		}

		if ( !g_bSuppressPrintfOutput || type == SPEW_ERROR )
			printf( "%s", pMsg );

		OutputDebugString( pMsg );
		
		if ( type == SPEW_ERROR )
		{
			printf( "\n" );
			OutputDebugString( "\n" );
		}

		if( g_pLogFile )
		{
			CmdLib_FPrintf( g_pLogFile, "%s", pMsg );
			g_pFileSystem->Flush( g_pLogFile );
		}

		// Dispatch to other spew hooks.
		FOR_EACH_LL( g_ExtraSpewHooks, i )
			g_ExtraSpewHooks[i]( pMsg );

		RestoreConsoleTextColor( old );
	}
	LeaveCriticalSection( &g_SpewCS );

	if ( type == SPEW_ERROR )
	{
		CmdLib_Exit( 1 );
	}

	return retVal;
}
Beispiel #8
0
unsigned __stdcall CThread::ThreadProc(LPVOID pv)
{
#ifdef _LINUX
  ThreadInit_t *pInit = (ThreadInit_t *)pv;
#else
  std::auto_ptr<ThreadInit_t> pInit((ThreadInit_t *)pv);
#endif
  
#ifdef _X360
        // Make sure all threads are consistent w.r.t floating-point math
	SetupFPUControlWord();
#endif

	CThread *pThread = pInit->pThread;
	g_pCurThread = pThread;

	g_pCurThread->m_pStackBase = AlignValue( &pThread, 4096 );

	pInit->pThread->m_result = -1;

	try
	{
		*(pInit->pfInitSuccess) = pInit->pThread->Init();
	}

	catch (...)
	{
		*(pInit->pfInitSuccess) = false;
#ifdef _WIN32
		pInit->pInitCompleteEvent->Set();
#endif
		throw;
	}
	
	bool bInitSuccess = *(pInit->pfInitSuccess);
#ifdef _WIN32
	pInit->pInitCompleteEvent->Set();
#endif
	if (!bInitSuccess)
		return 0;

	if ( !Plat_IsInDebugSession() && (pInit->pThread->m_flags & SUPPORT_STOP_PROTOCOL) )
	{
		try
		{
			pInit->pThread->m_result = pInit->pThread->Run();
		}

		catch (...)
		{
		}
	}
	else
	{
		pInit->pThread->m_result = pInit->pThread->Run();
	}

	pInit->pThread->OnExit();
	g_pCurThread = NULL;

#ifdef _WIN32
	AUTO_LOCK( pThread->m_Lock );
	CloseHandle( pThread->m_hThread );
	pThread->m_hThread = NULL;
#endif
	pThread->m_threadId = 0;

	return pInit->pThread->m_result;
}
bool Sys_IsDebuggerPresent()
{
	return Plat_IsInDebugSession();
}