Posts Tagged ‘gprof’

Utilización de gprof/gcov: cobertura de ramas (y II)

Tuesday, February 5th, 2008

Continuando con la temática del post anterior, vamos a ver en este caso, como chequear la cobertura lógica en bloques de código con condiciones de acceso más o menos complejas.

Supongamos el siguiente fichero de código main.c:

main.c

En este caso, el script de compilación y ejecución será compexec.sh:

compexec.sh

Nótese como la herramienta gcov ha sido ejecutada con las opciones -b y -c. Según “man gcov”:

  1. -b
    –branch-probabilities
    Write branch frequencies to the output file, and write branch summary info to the standard output. This option allows you to see how often each branch in your program was taken. Unconditional branches will not be shown, unless the -u option is given.
  2. -c
    –branch-counts
    Write branch frequencies as the number of branches taken, rather than the percentage of branches taken.

Es decir, pedimos a la herramienta que devuelva información sobre ejecución de las “ramas lógicas”, dando como resultado el fichero main.c.gcov:

main.c.gcov

Aquí podemos ver información, aunque un tanto críptica, sobre la ejecución de dos bloques if-else. Como puede verse, cada uno de ellos presenta cuatro ramas, numeradas de “branch 0″ a “branch 3″. Veamos a continuación la explicación de estos datos:

Supongamos la condición:

if (a || b) {
   x;
} else {
   y;
}

Esta condición (o combinación de condiciones) da lugar a 4 ramas, que se corresponden con las posibles combinaciones de valores booleanos de las dos variables:

a b
—-
0 0
0 1
1 0
1 1

Podemos reescribir esta condición como:

if (a == false) {
   // Branch 0
   if (b == false) {
      // Branch 2
      y;
   } else {
      // Branch 3;
      x;
   }
} else {
   // Branch 1
   x;
}

Supongamos ahora la condición:

if (a && b) {
   x;
} else {
   y;
}

Como antes, esta condición (o combinación de condiciones) da lugar a 4 ramas, que se corresponden con las posibles combinaciones de valores booleanos de las dos variables:

a b
—-
1 1
1 0
0 1
0 0

Podemos reescribir esta condición como:

if (a == true) {
   // Branch 0
   if (b == true) {
      // Branch 2
      x;
   } else {
      // Branch 3;
      y;
   }
} else {
   // Branch 1
   y;
}

En cualquiera de los casos anteriores, la herramienta gcov (con las opciones -bc) nos devuelve el número de veces que cada una de las ramas nombradas más arriba ha sido ejecutada.

Si se omite la opción -c, los resultados son porcentajes, de manera que la suma de las ejecuciones de todas las ramas deberá ser el 100 %.

Además, se puede deducir que, en cualquiera de los casos:

1.- (nº de ejecuciones de rama 0) + (nº ejecuciones rama 1) = (nº ejecuciones
del if

2.- (nº ejec rama 2) + (nº ejec rama 3) = (nº ejec rama 1)

En conclusión, podemos deducir qué líneas de código y ramas lógicas han sido ejecutadas y añadir/modificar los test cases necesarios para alcanzar la cobertura deseada.

[Código completo y resultados.]


Utilización de gprof/gcov para obtención de datos de cobertura (I)

Monday, February 4th, 2008

Vamos a ver, en unos pasos muy simples, cómo utilizar las herramientas gprof/gcov (integradas con el compilador gcc) para obtener información de cobertura de ejecución de una aplicación. Los resultados son aplicables a cualquier entorno en que dispongamos de estas herramientas (Linux, windows+cygwin, MacOSX+Xcode, etc).

Para empezar el código fuente, main.c:

main.c

A continuación, las instrucciones de compilación y ejecución, compexec.sh:

compexec.sh

Como se puede apreciar, son tres las opciones añadidas al compilador/linkador para obtener los resultados esperados:

  1. -pgEsto es lo que dice “man gcc” acerca de esta opción:

    Generate extra code to write profile information suitable for the analysis program gprof. You must use this option when compiling the source files you want data about, and you must also use it when linking.

    Es decir, prepara el ejecutable para generar información suscpetible de ser utilizada por gprof para obtener información de “profiling”. Tras la ejecución de la aplicación generada con esta opción, se crea el fichero gmon.out.

  2. -ftest-coverage
  3. -fprofile-arcsEstas dos opciones son las que indican al compilador que, durante la ejecución de la aplicación, debe generarse información de cobertura.

    [La salida "man gcc" para estas opciones es demasiado larga para incluirla aquí, pero puede verse en este enlace.]

    El ejecutable compilado/linkado con estas opciones genera los ficheros main.gcno y main.gcda, que contienen los datos utilizados por gcov para generar información “legible” de cobertura.

Así pues, una vez ejecutada la aplicación y obtenidos estos ficheros, basta con ejecutar el comando gcov:

$ gcov main.c

(tal como se ha incluido en el fichero compexec.sh) y como resultado se obtiene el fichero main.c.gcov:

main.c.gcov

El fichero de resultados muestra el número de veces que un statement ha sido ejecutado.

Las instrucciones marcadas con “#####” son aquellas no cubiertas por la ejecución de la aplicación.

[Código completo y resultados.]


Get Adobe Flash playerPlugin by wpburn.com wordpress themes