22 nov 2011

Test de cobertura de código con gcov

A la hora de determinar la validez del código programado, resulta útil analizar el mismo para determinar si las diferentes partes del mismo son todas probadas al pasar los test (una buena forma es hacer desarrollo guiado por test o TDD). Para ello, las herramientas GNU nos proporcionan gcov, que nos dará información diversa sobre éste tipo de análisis.
Existe diversa información a analizar cuando se realiza un análisis de cobertura de código (http://en.wikipedia.org/wiki/Code_coverage), aunque aquí nos limitaremos a anotar la manera de utilizarlo de forma mas básica.

Para utilizar gcov, deberemos compilar nuestro programa/as añadiendo las opciones -fprofile-arcs -ftest-coverage a la compilación (podemos añadirlo a CFLAGS p. ej.)

¡¡¡Importante!!! Si utilizamos alguna directiva de optimización de código (p. eje -O2) gcov no nos dará información útil, ya que las optimizaciones modificarán el análisis. Por tanto, dichas opciones han de ser eliminadas en la compilación para la cobertura de código.

Una vez compilado el programa, obtenemos un archivo .gcno con la información que necesita gcov.

A continuación, si ejecutamos el programa, se nos creará un archivo .gcda con los datos de la ejecución para interpretarlos con gcov.

Lo siguiente sería invocar a gcov con las opciones que necesitemos, por ejemplo:

#gcov programa.c

Ésto creará un archivo programa.c.gcov con toda la información sobre la cobertura del código. Si lo editamos, podemos ver que al lado de cada línea nos indica el número de veces que se ha ejecutado la linea en cuestión (y si se ha ejecutado claro). De esta forma podemos saber que partes del código han sido probadas y cuáles no.

Otra opción interesante es invocar gcov con la opción -b, que nos dará información probabilistica sobre las sentencias condicionales (análisis MC/DC y similares como se puede ver en el artículo de la wikipedia)

Por último, es posible generar informes html a partir de ésta información utilizando el script lcov en vez de gcov, inicialmente pensando para realizar estas tareas sobre el kernel de Linux, pero útil también para aplicaciones de usuario normales, aunque no genera información probabilistica sobre las sentencias condicionales.

La manera de utilizarlo es la siguiente:
  • Capturar la información.
#lcov -c -d directorio_de_trabajo -o nombre_archivo_salida.info
  • Generar html
#genhtml nombre_archivo_salida.info -o directorio_destino_html


Para usarlo en baterías de test, puede ser necesario utilizar las capacidades que tiene de combinar datos de distintas ejecuciones, para lo cual es recomendable ver man lcov.


10 mar 2011

Mezclar enlazado dinámico y estático C

A veces, en un programa en C, es necesario enlazar con bibliotecas estáticas, lo cual no es un problema, salvo que también necesites enlazar con otras dinámicas.
Por defecto, cuando invocamos el enlazador desde gcc, el enlazado se hace de manera dinámica, aunque podemos forzarlo con la opción -static para que se haga estática. De ésta forma, se incluirán en el ejecutable los códigos objeto de las funciones llamadas en él.
Pero, ¿y si lo que queremos es enlazar algunas bibliotecas de forma dinámica y otras de forma estática?
Pues la solución es simple, aunque creo que no óptima:

 -Wl,--whole-archive -lbiblio_estatica ...
-Wl,--no--whole-archive -lbiblio_dinamica ...
Con lo que mediante -Wl le decimos a gcc que le pase lo siguiente al enlazador ld.

Y digo que creo que no es óptima porque según el manual del enlazador ld, éstas opciones hacen que se incluya en el ejecutable los archivos completos que se indican a continuación, por lo que se introducirá código que el programa no use (o eso es lo que yo entiendo).

Después le pasamos la opción que anula la configuración de incluir todos los archivos

27 ene 2011

VIM: Elminar ^M en archivos de texto

En ocasiones, cuando abrimos archivos de texto plano con vim procedentes de "otros" sistemas operativos, nos encontramos con unos caracteres molestos al final de cada línea.

Para eliminarlos, existe un método muy sencillo desde el propio vim, ahí va la receta:

abrimos el archivo:

vim nombre_archivo.xxx

En modo comando usamos:

:%s/Ctrl+V,Ctrl+M//

"et voila"

esto nos puede servir para otras muchas sustituciones, ya que "%" significa "en todo el documento", y la "s" nos permite sustituir.

21 oct 2010

Herramientas de depuración: pstack (Linux)

Hoy he descubierto una utilidad que parece interesante, se llama pstack y permite ver la pila de un proceso invocándola con su PID.
Sólo es válida para Linux y en la arquitectura x86 de 32 bits, Además, es necesario que el proceso no haya sufrido un proceso de stripping de los simbolos para que sea útil.

Mas información en "man pstack"

7 sept 2010

Crear Tablas Latex a partir de excel o Open Document Spreadsheet

Haciendo uso de las macros Excel2Latex y Calc2Latex, podemos obtener el código LaTex para insertarlo directamente en un bloque ERT en Lyx o en el código Latex directamente. Consultar la instalación y uso de las mismas en la página correspondiente (buscar en google el nombre de los scripts).

17 abr 2010

Conectar mediante XDMCP a una maquina Linux

Para conectar a una máquina Linux mediante XDMCP desde OSX, tendremos que tener habilitada dicha funcionalidad en gdm.conf (o en /etc/gdm/custom.conf en xubuntu y similares) o en el archivo de configuración del gestor de ventanas usado. Mirar el archivo de ejemplo (/etc/gdm/gdm.conf-dpkg-bak) para ver las distintas opciones. Es conveniente hacer uso del parámetro que limita el máximo número de conexiones, porque puede suceder que tras una conexión que termina con fallo no podamos conectar de nuevo hasta reiniciar.

Una vez configurado correctamente, conectamos mediante:

/usr/X11R6/bin/Xnest :1 -query 192.168.0.12 -geometry 1024x768 -terminate

con la opción -terminate, hacemos que finalice la conexión cuando salgamos de la sesión remota, en vez de volver a la pantalla de login.
Con la opción -geometry podemos definir el tamaño de la ventana que veremos.

22 may 2009

Creación de presentaciones en Latex

Para crear presentaciones en Latex (con transiciones y todo no te vayas a pensar....) podemos usar el paquete Beamer. Para mayor comodidad podemos hacer uso de Lyx para hacerlo, para lo cual necesitamos instalar el paquete latex-beamer (en OSX viene con el instalador de Lyx) y seleccionamos el Layout  presentation (beamer).

Si no modificamos nada mas, las diapositivas saldran un poco simples, pero podemos usar temas para cambiar los colores, etc.
De forma simple, podemos poner en el preámbulo TeX lo siguiente:

\usetheme{nombre_Tema}

....

Convertir archivos .bin/.cue a .iso en Unix

Bueno, pues para convertir esos dichosos .CUE y .BIN a un .ISO como mandan los cánones podemos usar la herramienta GPL binchunker.
Bajamos el código fuente de la página, ejecutamos make y ya tendremos la aplicación bchunk. El uso es el sisguiente:

bchunk archivo.bin archivo.cue archivo.iso

Y ya tendríamos nuestro .ISO

18 may 2009

Usar número variable de columnas en Lyx

Al escribir un artículo en Latex con Lyx, me encontré el problema de que podía poner el mismo en dos columnas, pero eso me afectaba a todo el documento, y no podía por ejemplo poner el abstract en una única columna junto con el título, el autor y la fecha.
Entonces, google vino en mi ayuda y encontré la forma de manejar las columnas sin tener que modificar directamente el código .tex, y poder hacerlo directamente en Lyx.
Para hacerlo, introducimos en el preámbulo de Lyx (Documento-Configuración-Preámbulo Latex) lo siguiente:

\usepackage{multicol}

Y después, encerramos cada bloque que deseemos poner con un número distinto de columnas al del documento con un ERT:

\begin{multicols}{2}   \end{multicols}  
Y ya tendríamos lo que andábamos buscando

20 abr 2009

Trasteando con imagemagick

Imagemagick es un conjunto de herramientas para tratamiento de imágenes en modo consola, y que nos puede ser muy útil para cuando queremos hacer conversiones a conjuntos de archivos, o transformaciones rápidas (también cosas avanzadas pero de momento no se tanto).

Yo lo he usado para generar un pdf de unas páginas escaneadas de un documento.

En primer lugar tuve que rotar todas las paginas porque las habia colocado en el escáner al revés, así que utilicé la herramienta mogrify de imagemagick de la siguiente manera:

mogrify -rotate 180 nombre_archivos

En segundo lugar, usé la herramienta convert para pasar las imágenes de PNG a PDF y unirlas en un solo documento:

convert nombre archivos_PNG -adjoin nombre_archivo_PDF

et voila, ya tenemos nuestro PDF con los apuntes escaneados.

mas información en man imagemagick.

7 abr 2009

Descargar una pagina web completa con wget

Si queremos guardar una pagina web completa con todos sus enlaces
podemos hacerlo de forma sencilla con la herramienta wget.

En primer lugar es aconsejable crear un directorio donde guardaremos
todo (así no descargaremos los infinitos archivos en el directorio en el
que estemos, algo habitual para los novatillos con la consola)

Abrimos una consola, nos vamos a dicho directorio y hacemos:

wget -krc http://www.pagina_lo_que_sea.html

2 abr 2009

Detección de Lagunas de memoria en C y C++

Para comprobar las lagunas de memoria existen varias posibilidades, pero me centrare en dos, Valgrind y dmalloc.

La primera de ellas basta instalarla, y también podemos instalar un frontend llamado alleyoop.
Valgrind tiene varias opciones y permite hacer mas cosas además de comprobar la memoria, pero para nuestro fin la usaremos con:

valgrind --tool=memcheck --leak-check=yes nombre_programa

Es posible indicar que nos genere un archivo de log.
Para usar el alleyoop, debemos usarlo con:

alleyoop /ruta/al/nombre_programa

Evidentemente la ejecución del programa será mas lenta usando valgrind que normalmente.


La otra utilidad es dmalloc, que necesita incluir el archivo de cabecera dmalloc.h en el programa, y además compilarlo con la biblioteca dmalloc añadiendo -ldmalloc a la orden de compilación.
Después hay que configurar una variable de entorno y exportarla. Un ejemplo sería:

DMALLOC_OPTIONS=debug=0x44a40503,inter=1,log=logfile
export DMALLOC_OPTIONS
El valor hexadecimal de debug marca que tipo de comprobaciones se llevan a cabo. Para simplificar esta configuración existe un programa llamado dmalloc que podemos ejecutar en la consola, y que nos permite obtener el valor que debemos poner en la variable de entorno, según una serie de tokens correspondientes a las diferentes comprobaciones.

30 mar 2009

Analizando y aplicando diferencias con vimdiff

Pues resulta que se puede usar una extensión de Vim para analizar diferencias y aplicarlas entre varios archivos, usando una el comando:

vimdiff archivo1 archivo2

Para movernos por las diferencias, usaremos ]c y [c para ir a la siguiente y anterior diferencia.
Para aplicar las diferencias en uno u otro sentido usaremos

do obtiene la diferencia desde el otro archivo
dp aplica la diferencia sobre el otro archivo

También es posible realizar operaciones sobre un rango de líneas. Para mayor detalle, consultar
http://www.vim.org/htmldoc/diff.html

3 mar 2009

Instalación de Xenomai

Los ingredientes para este maravilloso cocktail de frutas son:

  • Fuentes del kernel a utilizar (Linux kernel)
  • Parche ADEOS para la arquitectura y versión del kernel que vamos a usar (adeos patches).
  • Fuentes de xenomai (xenomai sources).
  • Herramientas de desarrollo habituales para la compilación del kernel (gcc, make, etc...) o toolchain para la arquitectura a utilizar, en caso de que vayamos a hacer una compilación cruzada.
Con las manos en la masa
En primer lugar hay que aplicar el parche ADEOS sobre el kernel a utilizar (si es necesario aplicar otros parches al kernel, el de ADEOS es preferible que sea el último), para lo cual haremos

patch -p1 < ruta_al_parche/parche_adeos.patch

Desde el directorio principal del kernel.

Una vez hecho esto, entramos en la configuración del kernel (según prefiramos con menuconfig, xconfig, ...) y configuramos el mismo a nuestro gusto. Podemos ver como aparecen nuevas opciones en Real-Time sub-system así como en otros lugares y que son los puntos de configuración de ADEOS/Xenomai. Para una descripción detallada de la instalación y configuración visitar www.xenomai.org.

Hay que decir que en los fuentes de Xenomai existe un directorio ksrc donde podemos encontrar los parches mas comunes de ADEOS.

En segundo lugar descomprimimos los fuentes de Xenomai, y ejecutamos

scripts/prepare-kernel.sh --linux=path_to_linux_kernel_directory --adeos=parche_a_usar --arch=arquitectura

Si ya hemos aplicado el parche a mano, no es necesario poner la opción --adeos, y si lo hacemos tampoco pasa nada porque el script se dará cuenta de que ya está parcheado.

Una vez hecho esto, pasamos a configurar las fuentes de Xenomai para su compilación. Existen diversas opciones para ello, en función de la arquitectura que usemos, y de donde queramos instalar el resultado. Consultar el README que acompaña a las fuentes para determinar las opciones necesarias. Como ejemplo la compilación para un sistema integratorCP ARM.

./configure --host=arm-926ejs-linux --enable-arm-mach=integrator --enable-arm-arch=4
make DESTDIR=directorio_destino_instalacion install


Con esto y la imagen del kernel, ya tendríamos Xenomai listo para instalarlo, en función de si se trata de un PC o de un sistema empotrado, los siguientes pasos variaran para hacer que el sistema arranque nuestro nuevo kernel.

Tiempo Real Estricto con GNU/Linux y Xenomai

Xenomai es una solución utilizada para dotar al kernel de Linux de soporte para tiempo real estricto (hard real time), ya que éste no es capaz de proporcionar, por si solo, las capacidades necesarias para garantizar restricciones temporales estrictas (lo que no implica alta velocidad).
Según la definición que se hace en su propia pagina web, Xenomai es "un entorno de desarrollo en tiempo real que coopera con el núcleo Linux para proporcionar un respaldo omnipresente, independiente de la interfaz y muy cercano al tiempo real a aplicaciones de espacio de usuario, integrado completamente en el entorno GNU/Linux. Xenomai proporciona su propia API y capas de emulación («pieles» o «skins») para poder migrar desde otros RTOS más fácilmente. Ejemplos de estos son: pSOS+, VxWorks, VRTX, uiTRON, RTAI, POSIX."
Personalmente, lo de "omnipresente" me parece una mala traducción del termino anglosajón "pervasive" cuya traducción es también dominante o penetrante, aunque ninguna de ellas expresa correctamente el concepto.

De una forma mas llana, podemos decir que Xenomai proporciona estructuras de datos, funciones y tipos de datos que nos permiten desarrollar aplicaciones con restricciones de tiempo real estricto, que se integran perfectamente con un entorno GNU/Linux, y que además proporciona varias interfaces que hace más sencilla la adaptación de aplicaciones ya desarrolladas en otros sistemas operativos de tiempo real.

La instalación de Xenomai consta de dos partes:
  1. Parche para el kernel de Linux.
  2. Soporte y aplicaciones de espacio de usuario.
El parche para el kernel se trata de ADEOS (Adaptative Domain Enviroment for Operating Systems) que comparte las interrupciones y eventos generados por el sistema, de forma que colabora con el kernel para ofrecer las capacidades de tiempo real. De ésta forma, los servicios normales de Linux son considerados tareas de baja prioridad respecto a las tareas con restricciones de tiempo real, y éstas últimas no adolecen de latencias no deseadas.

En próximas entradas nos adentraremos en la instalación y uso de Xenomai.

2 mar 2009

Depuración con Core dumps

Un core dump es un archivo que contiene una imagen de la memoria de un proceso en el momento en el que sufrió un fallo (Segmentation fault) o se le envió una señal que produce su generación (señales cuyo Action es igual a Core).
Estos archivos son realmente útiles a la hora de depurar un programa, ya que nos ofrecen información de como se encontraba el mismo en el momento del fallo. Para utilizarlos, en primer lugar es necesario que el sistema tenga habilitada su generación, para lo cual usaremos el comando:

ulimit -c tamaño_maximo_en_bytes

Realmente con esto lo que hacemos es no poner límite al tamaño de los cores que se generen.
El comando ulimit permite variar otras cosas, como el número máximo de archivos abiertos por usuario/grupo.

Por defecto, el kernel nos generará el core dump con el nombre core, pero esto se puede modificar de forma permanente o solo mientras este el sistema arrancado.

No permanente
Modificamos el valor del archivo /proc/sys/kernel/core_pattern, donde podemos utilizar expresiones especiales que se expanden en ciertos valores útiles:

  • %% a single % character
  • %p PID of dumped process
  • %u (numeric) real UID of dumped process
  • %g (numeric) real GID of dumped process
  • %s number of signal causing dump
  • %t time of dump, expressed as seconds since the Epoch (00:00h, 1 Jan 1970, UTC)
  • %h hostname (same as nodename returned by uname(2))
  • %e executable filename (without path prefix)
  • %c core file size soft resource limit of crashing process (since Linux 2.6.24)
Así podemos poner por ejemplo que los cores se ubiquen en un directorio, y se generen con el PID del proceso correspondiente, la hora en que se ha producido, la señal que provoco el dump, el nombre del programa, etc...

Ejemplo:

echo "core.%p-%t" > /proc/sys/kernel/core_pattern


Además, es posible enviar el dump a la entrada de otro programa a través de una tubería (pipe) utilizando argumentos para el programa, entre los que pueden estar variables como las que hemos visto antes.

Ejemplo:

echo "|nombre_programa argumento1 argumento2 %p %e"

(Los argumentos 3 y 4 serán el PID y el nombre del ejecutable causante del dump)

Permanente
Para hacer los cambios de manera permanente, deberemos editar el archivo /etc/syslog.conf, y añadir en él una línea como:

kernel.core_pattern = patron_para_los cores

Donde el patrón se escribe de la misma forma que hemos visto anteriormente.

Este archivo permite configurar los valores de todos los archivos en /proc/sys, lo cual puede ser útil para otras muchas cosas además de los cores.

Para una información mas detallada y precisa consultar man core y man 5 sysctl.conf.

Por último, es posible generar core dumps de programas en ejecución con la orden gcore (ver man gcore).

13 dic 2008

fórmulas en gráficos con xfig (y de ahi a documentos Latex)

Es posible insertar fórmulas Latex en gráficos creados con Xfig, y que posteriormente podremos usar en documentos Latex (o por ejemplo con Lyx).

Para hacerlo, tendremos que escribir un bloque de texto en xfig, habilitar el flag "Special", usar una fuente Latex, y escribir la fórmula con syntaxis Latex encerrada entre caracteres $. Por ejemplo:

señal $Y_{i}(t)$

Cuando tenemos nuestro gráfico, lo exportamos con xfig a Combined PS/Latex(both formats), lo que nos creará dos archivos archivo_fig.pstex_t y archivo_fig.pstex.
Creamos ahora un archivo figura.tex con el código:


\documentclass{article}
\usepackage{epsfig}
\usepackage{color} (puede que no sea necesario)
\setlength{\textwidth}{100cm}
\setlength{\textheight}{100cm}
\begin{document}
\pagestyle{empty}
\input{figura.pstex_t}
\end{document}
Lo guardamos y ejecutamos:
latex figura.tex
Obtenemos un archivo figura.dvi, que convertiremos a EPS (Encapsulated Postcript) con
la orden:
dvips -E figura.dvi -o figura.eps
Una vez que tenemos el archivo .eps, lo incluimos como imagen en nuestro documento Latex(o Lyx).

12 dic 2008

Creacion de parches con diff

Si tenemos un proyecto contenido en un directorio, con sus subdirectorios y archivos asociados, es útil crear parches cuando hacemos modificaciones.
1 ejemplo claro es cuando modificamos las fuentes del kernel de Linux para adaptarlo a alguna plataforma especial.

El modo de proceder es simple, una vez que se sabe claro.
Supongamos que tenemos el directorio linux-2.6.26-modificado y el directorio original de la misma versión linux-2.6.26, y queremos crear un parche para no tener que almacenar para siempre todos los archivos del kernel, por si los volvemos a necesitar. Crearemos el parche con la siguiente orden, desde el directorio que contiene a ambos directorios:

diff -Naur linux-2.6.26 linux-2.6.26-modificado > nombre_parche.patch

De esta forma creamos el parche nombre_parche.patch que contiene todos los cambios del directorio modificado respecto del original.

Cuando necesitemos de nuevo nuestro kernel modificado, descargamos la version del mismo original, copiamos el parche en su directorio, y ejecutamos la siguiente orden desde dentro de dicho directorio:

patch -p1

Y ya tendriamos el kernel con las modificaciones que realizamos en su día.

1 dic 2008

Argumentos en la linea de órdenes para programas en C

Existen unas funciones muy útiles para "filtrar" los argumentos en la linea de ordenes pasados a un programa en C al estilo Unix, esto es:

nombre_programa -o archivo.txt -d 40....

Cuando tenemos el código de nuestro programa, los argumentos son pasados a la funcion main() en dos variables llamadas argc(entero) y argv(array de punteros a cadenas de caracteres, es decir **), siendo argv[0], el primer argumento pasado, argv[1] el segundo, y asi sucesivamente hasta alcanzar argc argumentos.


Tenemos las funciones getopt y getopt_long que nos permiten "parsear" o analizar sintácticamente los argumentos que le pasemos. A estas funciones se les pasa directamente argc y argv, además de una cadena en la que se indican los caracteres de opción a contemplar y si llevan o no un parámetro asociado a continuación. Las funciones devuelven el carácter opción leído o -1 en caso de haber alcanzado el final.
Con esto podemos extraer las opciones que nos han pasado como argumentos independientemente del orden, ya que llamaremos a la función en cuestión (getop o getopt_long)hasta alcanzar el final, indicando en cada ejecución todas las opciones.
1 ejemplo:

int main(int argc,char **argv)
{
int c;
while((c=getopt(argc,argv,"p:n:b:t:d:m:")) != -1){
switch (c) {
case 'p':
//Código asociado a la ipción -p.
break;
case 'n':
//Código asociado a la ipción -n.
break;
case 'b':
//Código asociado a la ipción -b.
.
.
.
default:
printf("Uso: app_spi_slave [-p X][-n X][-b X][-t X][-d X]");
return 1;
}
}
return 0;
}


Como podemos ver, el tercer argumento de getopt es una cadena con los caracteres asociados a cada opción, seguida del carácter ":" que indica que después de dicha opción viene un argumento. Si no hay argumento asociado, basta con no poner el carácter ":".
Para usar el valor pasado a la opción, tenemos la variable optarg, que contiene el argumento de la opción que está siendo analizada. Ésta variable es una cadena de caracteres, por lo que habrá que convertirla al formato que necesite (si es un numero podremos usar al función atoi()).
Como podemos ver en el ejemplo, la función itera una vez en la lista de argumentos, quedándose preparada para acceder a la siguiente cuando la volvamos a ejecutar.

Hemos utilizado la función getopt, pero ¿que hay de getopt_long?
Pues esta segunda función nos permite hacer lo mismo, salvo que tiene dos argumentos mas, uno de ellos es un array de estructuras de tipo struct opts (definida en getopt.h) en las que se asocia un nombre largo a cada opción para poder hacer algo como lo siguiente:

nombre_programa --polarity 1 --outpu nombre_arcivo.txt ....

Para mas información se recomienda acudir a las paginas man para getopt ejecutando:
man 3 getopt

17 nov 2008

Makefiles(II) Dejando que gcc nos de las dependencias

Si no queremos comernos la cabeza para determinar cuales son las dependencias de un proyecto, podemos hacer que el compilador GNU nos las de.
Para ellos, si tenemos por ejemplo los archivos main.c funcinoes1.c y funcinoes2.c e includes.h y queremos ver cuáles son las dependencias, bastará con ejecutar:

gcc -MM main.c funciones1.c funciones2.c

y obtendremos las reglas para el Makefile.