Predicados

No puede utilizar predicados cuando la ejecución de cláusulas en puntos de analizador debe realizarse condicionalmente. La sección de predicado se identifica mediante la presencia de la palabra clave when inmediatamente después de la sección de especificación de analizador. El propio predicado consta de expresiones condicionales de estilo C regulares con paréntesis delimitador.

Existen algunas restricciones en las expresiones dentro de la sección de predicado:

  • Las variables de clase de kernel no están permitidas en el predicado.
  • Las variables de clase automáticas no están permitidas en el predicado.
  • Las variables de tipo de coma flotante no están permitidas en el predicado.
  • Las funciones Vue no están permitidas dentro de un predicado.
  • Los efectos secundarios no están permitidos dentro de un predicado, por lo que el operador de asignación = y sus derivados como + =, | =, etc. no están permitidos.
  • Los parámetros noveno y superior pasados a una función (las variables de clase de entrada __arg9, __arg10, etc.) no están permitidos en el predicado.

La ejecución condicional de acciones específicas dentro de una cláusula es posible utilizando if ... else sentencia que funciona como la sentencia análoga en C. Sin embargo, si la cláusula completa se va a emitir condicionalmente, es preferible utilizar predicados en su lugar porque ProbeVue está diseñado para optimizar la ejecución de predicados.

Nota: Cuando un punto de analizador puede activarse para más de un proceso, el uso de variables locales de hebra dentro del predicado es una forma excelente de reducir el impacto global en el rendimiento de la habilitación del analizador. Es preferible colocar comprobaciones condicionales dentro de un predicado que utilizar la sentencia if .

El script siguiente utiliza variables locales de hebra dentro de predicados para detectar de forma eficaz cuándo se graba una serie de caracteres determinada en un archivo específico. También muestra un ejemplo de utilización de la sentencia if dentro del bloque de acciones de una cláusula con un predicado. Tanto el nombre de archivo como la serie de caracteres se pasan como parámetros al script utilizando parámetros posicionales de shell.

/*
 * Filename : chkfilewrite.e
 *
 * Capture when someone writes a particular word to a specific file 
 * takes 2 arguments: filename and word
 *
 * assumes file name is < 128
 *
 * Usage: probevue chkfilewrite.e \"<filename>\" \"<string>\"
 *
 *	The backslashes above are necessary to prevent shell
 *	from stripping the double quotation mark.
 */

int open(char *fname, int m, int p);
int write(int fd, char *s, int size);

@@syscall:*:open:entry
{
	__auto String fname[128];

	fname = get_userstring(__arg1, -1);

	if (fname == $1)
		thread:opening = 1;
}

@@syscall:*:open:exit
	when (thread:opening == 1)
{
	thread:fd = __rv;
	thread:opening = 0;

}

@@syscall:*:write:entry
	when (thread:fd == __arg1)
{
	__auto String buf[128];

	if (__arg3 < 128)
		buf = get_userstring(__arg2, __arg3);
	else
		buf = get_userstring(__arg2, 128);

	if (strstr(buf, $2)) {
		printf("%d wrote word to file.\n", __pid);
		exit();
	}
}

Para ejecutar este programa para comprobar cuándo alguien escribe la serie "Error" en el archivo foo.log , puede emitir el mandato siguiente:

probevue chkfilewrite.e \"foo.log\" \"Error\"
Nota: puede mejorar el script anterior añadiendo un analizador close para detectar cuándo se cierra el archivo para evitar que el script capte la palabra después de que se cierre el archivo original y se abra uno nuevo y se vuelva a utilizar el mismo número de descriptor de archivo.