Beispiel #1
0
/*
 * Check if time slice since last check-for-interrupts (CFI) has been exceeded
 */
void
TimeSliceCheck(const char *file, int line)
{
	Assert(gp_test_time_slice);
	Assert(IsValidReportLevel(gp_test_time_slice_report_level));

	struct rusage ru;
	int32 elapsedMs = 0;

	/* CFI is disabled inside critical sections */
	if (0 != InterruptHoldoffCount || 0 != CritSectionCount)
	{
		return;
	}

	/* get current user time */
	if (getrusage(RUSAGE_SELF, &ru) != 0)
	{
		elog(ERROR, "Time slicer: Failed to retrieve user time");
	}

	elapsedMs = timeElapsedMs(&ru.ru_utime, &userTimeLastCFI);

	Assert(0 <= elapsedMs);

	/* check elapsed time since last CFI  */
	if (gp_test_time_slice_interval < elapsedMs)
	{
		void *stackAddressesCurrent[MAX_FRAME_DEPTH];
		uint32 stackDepthCurrent = gp_backtrace(stackAddressesCurrent, MAX_FRAME_DEPTH);

		char *stackTraceLastCFI = gp_stacktrace(stackAddressesLastCFI, stackDepthLastCFI);
		char *stackTraceCurrent = gp_stacktrace(stackAddressesCurrent, stackDepthCurrent);

		/* report time slice violation error */
		ereport(gp_test_time_slice_report_level,
				(errmsg("Time slice of %d ms exceeded at (%s:%d), last CFI before %d ms.\n"
						"Stack trace of last CFI:\n%s\n"
						"Current stack trace:\n%s\n",
						gp_test_time_slice_interval,
						file,
						line,
						elapsedMs,
						stackTraceLastCFI,
						stackTraceCurrent)));
	}

	/* reset time slice */
	userTimeLastCFI = ru.ru_utime;
	stackDepthLastCFI = gp_backtrace(stackAddressesLastCFI, MAX_FRAME_DEPTH);
}
Beispiel #2
0
/*
 * check if lightweight lock(s) are held;
 * print stack trace where lock(s) got acquired and error out;
 */
void
LWLockHeldDetect(const void *pv, int lockmode)
{
	Assert(gp_test_deadlock_hazard);
	Assert(IsValidReportLevel(gp_test_deadlock_hazard_report_level));

	const LOCKTAG *locktag = (const LOCKTAG *) pv;

	if (0 < LWLocksHeld())
	{
		void *stackAddressesCurrent[MAX_FRAME_DEPTH];
		uint32 stackDepthCurrent = gp_backtrace(stackAddressesCurrent, MAX_FRAME_DEPTH);
		char *stackTraceCurrent = gp_stacktrace(stackAddressesCurrent, stackDepthCurrent);

		const char *stackTraces = LWLocksHeldStackTraces();
		Assert(NULL != stackTraces);

		/* report time slice violation error */
		ereport(gp_test_deadlock_hazard_report_level,
				(errmsg("Attempting to acquire database lock (%s:%d:%d:%d:%d) while holding lightweight lock (%d:%p).\n"
						"Stack trace(s) where lightweight lock(s) got acquired:\n%s\n"
						"Current stack trace:\n%s\n",
						GetLockmodeName(locktag->locktag_lockmethodid, lockmode),
						locktag->locktag_field1,
						locktag->locktag_field2,
						locktag->locktag_field3,
						locktag->locktag_field4,
						LWLockHeldLatestId(),
						LWLockHeldLatestCaller(),
						stackTraces,
						stackTraceCurrent)));
	}
}
Beispiel #3
0
/*
 * Build string containing stack traces where all exclusively-held
 * locks were acquired;
 */
const char*
LWLocksHeldStackTraces()
{
	if (num_held_lwlocks == 0)
	{
		return NULL;
	}

	StringInfo append = makeStringInfo();	/* palloc'd */
	uint32 i = 0, cnt = 1;

	/* append stack trace for each held lock */
	for (i = 0; i < num_held_lwlocks; i++)
	{
		if (!LWLOCK_IS_PREDEFINED(held_lwlocks[i]))
		{
			continue;
		}

		appendStringInfo(append, "%d: LWLock %d:\n", cnt++, held_lwlocks[i] );

		char *stackTrace =
				gp_stacktrace(held_lwlocks_addresses[i], held_lwlocks_depth[i]);

		Assert(stackTrace != NULL);
		appendStringInfoString(append, stackTrace);
		pfree(stackTrace);
	}

	Assert(append->len > 0);
	return append->data;
}