Tentative tracing

Tentative tracing permits intelligent filtering of data and will reduce the actual amount of trace data that is presented to you and which you need to analyze. This has the excellent side effect of preventing buffer overflow problems if you can ensure that the tentatively collected data be discarded or committed early.

The following script is an example of using tentative tracing functions to capture trace data only when necessary:

/* 
 * File: tentative.e
 *
 *	Print details when write system call takes longer than a
 *	specified number of microseconds
 *
 *	Usage: probevue tentative.e <processID> <microseconds> 
 */
int write(int fd, char *buf, int size);

@@BEGIN
{
	probev_timestamp_t  ts1, ts2;
}

@@syscall:$1:write:entry 
{
	__auto String buf[256];

	if (__arg3 < 256)
		buf = get_userstring(buf, __arg3);
	else
		buf = get_userstring(buf, 256);

	start_tentative("write");

	/* print out all the data associated with the write */
	stktrace(PRINT_SYMBOLS|GET_USER_TRACE, -1);

	printf("fd = %d, size = %d\n", __arg1, __arg3);

	/* Prints 256 bytes of buf, even though size may be < 256 */
	trace(buf);

	end_tentative("write");

	/* Get timestamp for when we entered write: do this at the end of
	 * the probe to reduce probe effect
	 */
	ts1 = timestamp();
}
	
/* If we started probing in the middle of write, ts1 will be zero,
 * ignore that case with a predicate
 */
@@syscall:$1:write:exit
	when (ts1 != 0)
{
	/* diff_time() may return up to a 64-bit value, but we 
	 * use an int here since we don't expect the difference to
	 * larger than a few hundred microseconds at the most.
	 */
	int micros;

	/* Get timestamp for when we exited write: do this at the beginning of
	 * the probe to reduce probe effect
	 */
	ts2 = timestamp();

	micros = diff_time(ts1, ts2, MICROSECONDS);

	start_tentative("write");
	printf("Return value from write = %d\n", __rv);
	end_tentative("write");

	if (micros > $2) {
		/* Can mix normal trace with tentative also  */
		printf("Time to write = %d, limit =%d micro seconds\n",
			micros, $2);
		commit_tentative("write");
		exit();
	}
	else
		discard_tentative("write");
}