Script variables

A script variable is either an automatic, thread-local, or global class variable.

Script variables exist only inside the context of a Vue script and their values are assigned from the script. Further, they can only be accessed or modified inside the script that defines them.

In general, you must explicitly declare the data type of a script variable through a declaration statement. However, the compiler can implicitly determine the data type of a program variable in some limited cases if the first reference to the variable is an assignment operation with the variable on the left-hand side of the assignment operator.

Implicit type determination for integral types

To be assigned an integral type, the right-hand side of the assignment must be in one of the following situations:

  • A constant number.
  • Another variable of integral type including built-in variables. Assigning from a variable whose type is not known is an error.
  • A Vue function that returns an integral type like the diff_time function.
  • Casting the expression on the right-hand side to an integral type, although this might give a warning in some cases.
  • An expression involving any of the preceding situations.

The variable takes its type in addition to its value based on the expression on the right-hand side. In addition, the class of the variable can be assigned to the variable by prefixing it to the variable. The following script demonstrates some examples:

/*
 * File:	implicit2.e
 * Usage:	Demonstrates implicit assignment for integer types 
 */

int read(int fd, char *p, long size);

@@BEGIN
{
	count = 404;			/* count: int of global class */
	zcount = 2 * (count - 4);	/* zcount: int of global class */
	llcount = 33459182089021LL;  	/* lcount: long long of global class */
	lxcount = 0xF00000000245B20LL;	/* xcount: long long of global class */

}

@@syscall:$1:read:entry
{
	__auto probev_timestamp_t ts1, ts2;
	int gsize;
	ts1 = timestamp();
	auto:dcount = llcount - lxcount;  /* dcount: long long of auto class */ 

	auto:mypid = __pid;	/* mypid:  pid_t (64-bit integer) of automatic class */
	fd = __arg1;		/* fd: int of global class */

	/* The following cast will likely cause a compiler warning
	 * but can be ignored here
	 */
	global:bufaddr = (long)__arg2;	/* bufaddr: long of global class */

	gsize = __arg3;
	thread:size =  gsize + 400;	/* size: int of thread-local class */

	printf("count = %d, zcount = %lld\n", count, zcount);
	printf("llcount = %lld, lxcount = 0x%016llx, diff = %lld\n",
			llcount, lxcount, dcount);
	printf("mypid = %ld, fd = %d, size = %d\n", mypid, fd, size);
	printf("bufaddr = 0x%08x\n", bufaddr);
	ts2 = timestamp();
	
	auto:diff = diff_time(ts1, ts2, MICROSECONDS);	/* diff: int of automatic class */
	
	printf("Time to execute = %d microseconds\n", diff);
	
	exit();
}
Note: The presence in the preceding script of a shell positional-like parameter, namely the $1 symbol in the @@syscall:$1:read:entry probe specification. The syscall probe manager allows a process ID for the second field to indicate that the system call probe point must be enabled for a specific process only. Rather than hard-code a specific process ID, the second field has been set to a shell positional parameter in this script to permit the actual process ID to be passed as an argument at the time the script is issued. The probevue command replaces any shell positional parameters in the script with the respective arguments passed on the command line.

Assuming that you are probing a process that has process ID 250000, the following script shows an example of running the implicit2.e script.

# probevue implicit2.e 250000
WRN-100: Line:29 Column:26 Incompatible cast
count = 404, zcount = 800
llcount = 33459182089021, lxcount = 0x0f00000000245b20, diff = -1080830451389212643
mypid = 250000, fd = 10, size = 4496
bufaddr = 0x20033c00
Time to execute = 11 microseconds

In the preceding example, the $1 symbol in the script is automatically replaced with "250000", thus restricting the read system call entry probe point to the process with process ID equal to 250000.

Implicit type determination for string type

To be assigned a string type, the right-hand side of the assignment must be in one of the following situations:

  • A string literal that is a sequence of characters within double quotation mark.
  • Another variable of type string including built-in variables.
  • A Vue function that returns a string like the et_userstring function.
  • An expression involving any of the preceding situations.

The following example demonstrates implicit string type assignment:

/*
 * File:	implicit3.e
 * Usage:	Demonstrates implicit assignment for string types 
 */

int write(int fd, char *p, long size);

@@BEGIN
{
	s1 = "Write system call:\n";
}

@@syscall:$1:write:entry
{
	String s2[40];
	
	wbuf = get_userstring(__arg2, __arg3);

	s2 = s1;

	zbuf = s2;

	pstring = zbuf + wbuf;

	printf("%s\n", pstring);
}

@@syscall:$1:write:exit
{
	ename = __pname;
	printf("Exec name = %s\n", ename);
	exit();
}

A process ID must be passed as an argument to the script when issuing it to replace the $1 shell positional parameter variable.

Implicit type determination for list type

To be assigned a list type, the right-hand side of the assignment must be the list() function. list() function is supported from any clause.