void CrashHandler::ForceDeadlock( RString reason, uint64_t iID )
{
	CrashData crash;
	memset( &crash, 0, sizeof(crash) );

	crash.type = CrashData::FORCE_CRASH;

	GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL );

	if( iID == GetInvalidThreadId() )
	{
		/* Backtrace all threads. */
		BacktraceAllThreads( crash );
	}
	else
	{
		BacktraceContext ctx;
		if( !GetThreadBacktraceContext( iID, &ctx ) )
			reason += "; GetThreadBacktraceContext failed";
		else
			GetBacktrace( crash.BacktracePointers[1], BACKTRACE_MAX_SIZE, &ctx );
		strncpy( crash.m_ThreadName[1], RageThread::GetThreadNameByID(iID), sizeof(crash.m_ThreadName[0])-1 );
	}

	strncpy( crash.m_ThreadName[0], RageThread::GetCurrentThreadName(), sizeof(crash.m_ThreadName[0])-1 );

	strncpy( crash.reason, reason, min(sizeof(crash.reason) - 1, reason.length()) );
	crash.reason[ sizeof(crash.reason)-1 ] = 0;

	RunCrashHandler( &crash );

	_exit( 1 );
}
Example #2
0
void ReportBacktrace()
{
    static const int framesToShow = 31;
    static const int framesToSkip = 2;
    void* samples[framesToShow + framesToSkip];
    int frames = framesToShow + framesToSkip;

    GetBacktrace(samples, &frames);
    PrintBacktrace(samples + framesToSkip, frames - framesToSkip);
}
void CrashHandler::ForceCrash( const char *reason )
{
	CrashData crash;
	memset( &crash, 0, sizeof(crash) );

	crash.type = CrashData::FORCE_CRASH;
	strncpy( crash.reason, reason, sizeof(crash.reason) );
	crash.reason[ sizeof(crash.reason)-1 ] = 0;

	GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL );

	RunCrashHandler( &crash );
}
Example #4
0
int TestGetBacktrace()
{
    int size;
    int sizeMinus1;
    struct TBacktraceRecord* backtrace = GetBacktrace(&size, 0, 1);
    REQUIRE_NOT_EQUAL(backtrace, 0);
    REQUIRE_STRINGS_EQUAL(backtrace->Symbol_, "TestGetBacktrace");
    REQUIRE_STRINGS_EQUAL(backtrace[1].Symbol_, "main");
    free(backtrace);
    backtrace = GetBacktrace(&sizeMinus1, 1, 10);
    REQUIRE_NOT_EQUAL(backtrace, 0);
    REQUIRE_EQUAL(size - 1, sizeMinus1);
    REQUIRE_STRINGS_EQUAL(backtrace->Symbol_, "main");
    free(backtrace);
    backtrace = GetBacktrace(&size, 100, 10);
    REQUIRE_EQUAL(backtrace, 0);
    REQUIRE_EQUAL(errno, ERANGE);
    backtrace = GetBacktrace(&size, 100, 0x7fffffff);
    REQUIRE_EQUAL(backtrace, 0);
    REQUIRE_EQUAL(errno, EDOM);
    return 0;
}
Example #5
0
void CrashHandler::ForceCrash( std::string const &reason )
{
	CrashData crash;
	std::memset( &crash, 0, sizeof(crash) );

	crash.type = CrashData::FORCE_CRASH;
	std::strncpy( crash.reason, reason.c_str(), sizeof(crash.reason) );
	crash.reason[ sizeof(crash.reason)-1 ] = 0;

	GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, nullptr );

	RunCrashHandler( &crash );
}
static void BacktraceAllThreads( CrashData& crash )
{
	int iCnt = 1;
	uint64_t iID;
	
	for( int i = 0; RageThread::EnumThreadIDs(i, iID); ++i )
	{
		if( iID == GetInvalidThreadId() || iID == RageThread::GetCurrentThreadID() )
			continue;
		
		BacktraceContext ctx;
		if( GetThreadBacktraceContext( iID, &ctx ) )
			GetBacktrace( crash.BacktracePointers[iCnt], BACKTRACE_MAX_SIZE, &ctx );
		strncpy( crash.m_ThreadName[iCnt], RageThread::GetThreadNameByID(iID), sizeof(crash.m_ThreadName[0])-1 );
		
		++iCnt;
		
		if( iCnt == CrashData::MAX_BACKTRACE_THREADS )
			break;
	}
}
void CrashHandler::CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc )
{
	static volatile bool bInCrashSignalHandler = false;
	if( bInCrashSignalHandler )
	{
		safe_print( 2, "Fatal: crash from within the crash signal handler\n", NULL );
		_exit(1);
	}

	bInCrashSignalHandler = true;

	/* Work around a gcc bug: it reorders the above assignment past other work down
	 * here, even if we declare it volatile.  This makes us not catch recursive
	 * crashes. */
	asm volatile("nop");

	CrashData crash;
	memset( &crash, 0, sizeof(crash) );

	crash.type = CrashData::SIGNAL;
	crash.signal = signal;
	crash.si = *si;

	BacktraceContext ctx;
	GetSignalBacktraceContext( &ctx, uc );
	GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, &ctx );
#if defined(HAVE_DECL_SIGUSR1) && HAVE_DECL_SIGUSR1
	if( signal == SIGUSR1 )
		BacktraceAllThreads( crash );
#endif

	strncpy( crash.m_ThreadName[0], RageThread::GetCurrentThreadName(), sizeof(crash.m_ThreadName[0])-1 );

	bInCrashSignalHandler = false;

	/* RunCrashHandler handles any recursive crashes of its own by itself. */
	RunCrashHandler( &crash );
}