Surviving the Night

El blog de Pablo Doval sobre .NET, SQL, WinDbg...

Gimme Three Steps: Creando nuestro Servidor de Símbolos

Hace unos días, conversando con Rodri y con Jose Luis, surgió la necesidad de crear un documento interno de Plain Concepts acerca de la utilización de symstore para la creación de un servidor de símbolos a nivel de empresa. Al momento nos dimos cuenta de que esto podía interesar a mas geeks como nosotros, así que he decidido crear una guía muy breve para la creación de un servidor de símbolos básico.

¡Espero que os resulte interesante!

¿Un Servidor de Símbolos? ¿Para que quiero yo eso?

NOTA: En esta entrada no voy a explicar que son los símbolos, ni para que nos sirven, etc. Todo eso está explicado en múltiples artículos de la MSDN, en la documentación de los depuradores correspondientes y entradas de blog tan magníficas como esta. Y no es por que sea mía :)

Como ya sabréis los que me conocéis personalmente, para mi una sesión de depuración post-mortem es como la quema de iglesias para los blackmetaleros nórdicos; una fuente de diversión inagotable. Sin embargo siempre hay momentos frustrantes, y casi todos ellos tienen que ver con la carencia de símbolos apropiados, o el echo de que WinDbg no puede localizarlos adecuadamente.

Para facilitar la vida a nuestros depuradores y herramientas varias que necesiten acceder a esta información simbólica de depuración vamos a construir un servidor de símbolos donde se almacenaran tanto los símbolos de nuestras aplicaciones como los que nos descarguemos de otros servidores, como el servidor de símbolos públicos de Microsoft (http://msdl.microsoft.com/download/symbols).

Construyendo nuestro Servidor de Símbolos

Vamos a necesitar de tres simples pasos para construir el servidor de símbolos:

  • Obtener un lugar físico donde almacenar los símbolos:

Esta parte es la mas sencilla. Necesitamos un lugar donde almacenar los ficheros .pdb, para lo que crearemos un directorio en algún servidor accesible a nivel de nuestra organización y compartiremos esta carpeta. Así de simple :)

En el resto del articulo supondremos que hemos creado un share llamado Symbols en el servidor DevSrv01. Por tanto, el servidor de símbolos se encontrará en \\DevSer01\Symbols.

  • Configurar las herramientas para que utilicen ese lugar como servidor de símbolos:

Ahora debemos instruir a nuestra aplicación de que busque los símbolos en nuestro servidor concreto. En el caso de WinDbg podemos recurrir directamente a la configuración de la ruta de búsqueda de símbolos desde File –> Symbol File Path… o Ctrl+S. Desde ahí podemos establecer la ruta, que en nuestro ejemplo bien podría ser “SRV*\\DevSrv01\Symbols*http://msdl.microsoft.com/download/symbols”, indicando que el servidor de símbolos estará en nuestro servidor, y que también buscará en el servidor público de símbolos de Microsoft.

NOTA: Para mas información respecto a las cadenas de búsqueda de símbolos, recomiendo mirar la documentación de las Debugging Tools For Windows.

image

A medida que vayamos recargando símbolos (por ejemplo, mediante .reload en WinDbg), buscara la presencia de la versión correcta de los mismos en el servidor de símbolos (\\DevSrv01\Symbols) y, caso de no encontrarlos, iria al siguiente elemento en la cadena de búsqueda y los descargaría, copiandolos en el servidor \\DevSrv01\Symbols; de este modo, la segunda vez que fuera necesario cargar los símbolos, estos ya se encontrarían en nuestro nuevo y flamante servidor.

Una alternativa más práctica es emplear la variable de entorno _NT_SYMBOL_PATH, estableciéndola a nuestra cadena de búsqueda de símbolos. Prácticamente todas las aplicaciones que hace uso de los símbolos intentan buscar primero en esa variable de entorno, como es el caso de WinDbg, adplus, etc… Sin embargo, hay una notable excepción: el Process Explorer de SysInternals. Como seguramente sabréis, ésta magnifica herramienta también puede emplear los símbolos para generar volcados de memoria, ver la información de los call stacks de los diferentes threads de un proceso en ejecución, etc. En esta herramienta tendremos que establecer el servidor de símbolos manualmente, ya que no lee de _NT_SYMBOL_PATH. ¡Avisados estais! :)

  • Poblar el servidor de símbolos con cada nueva build:

Como ya sabréis, el mayor problema de los servidores de símbolos es mantener el orden dentro del caos que suponer tener múltiples versiones de un mismo módulo. Con cada nueva compilación, las direcciones de memoria de los distintos objetos pueden cambiar, asi como los offset, etc. Si intentamos depurar un proceso o un volcado de memoria con una versión incorrecta de los módulos los resultados pueden ser imprevisibles.

Os voy a comentar un ejemplo típico de depuración con símbolos incorrectos que seguro que os suena a más de uno: ¿alguna vez habéis realizado una depuración paso a paso con un depurador integrado en el entorno de desarrollo, y habéis comprobado que, en cierto momento, la línea que estáis ejecutando apunta a una línea inexistente o en blanco? Eso generalmente se debe a la utilización de unos .PDBs antiguos. Por ejemplo, se han agregado unas cuantas líneas de código a un método, pero al depurar empleamos la información de cuando ese método ocupaba menos, etc. Ala.. ¡un nuevo misterio resuelto! xD

Para evitar estos problemas, lo mejor es asegurarnos de que, cada vez que realizamos una nueva compilación, copiamos los nuevos .PDB al servidor de símbolos. La idea es buena, pero ahora tenemos que ver como la implementamos; daros cuenta que no puedo copiar directamente el fichero .pdb porque habría colisión de nombres. Si tengo un ensamblado llamado miEnsamblado.exe, y lo compilo cinco veces, tendré cinco ficheros miEnsamblado.pdb. Hay que buscar un mecanismo que permita almacenarlos sin que se sobrescriban, y haciendo posible que una herramienta que consuma los símbolos pueda coger el adecuado para una versión concreta.

Esto se consigue a través de una estructura de directorios especial en el servidor, basada en un hash del modulo, que no vamos a explicar en detalle en esta entrada. Lo que si os diré es que, gracias a una pequeña utilidad llamada symstore, que se distribuye con las propias Debugging Tools for Windows, podemos agregar nuevos .PDBs a nuestro servidor y automática se colocarán correctamente.

Un ejemplo de uso de symstore sería el siguiente:

symstore add /r /f c:\sources\aplicacion\bins\*.* /s \\DevSrv01\Symbols /t "Aplicacion 1" /v "Build 123"

En ese ejemplo agregamos al servidor todos los símbolos que se encuentran en la ruta definida, especificando el nombre de producto (/t) y la versión (/v). Para ver todos los parámetros, nuevamente recomiendo recurrir a la documentación de las Debugging Tools for Windows.

Ahora solo necesitamos automatizar el proceso después de la build, ya sea mediante una acción post-build, msbuild, o vuestro mecanismo favorito :)

Resumen

En este articulo no hemos entrado en profundidad en ninguno de los puntos; no hemos explicado que son los símbolos y para que valen, ni la sintaxis de la ruta de búsqueda de símbolos, ni como se genera el hash de cada versión de los símbolos y como éste se emplea para estructurarlos en el sistema de ficheros, etc. No, ese no era el objetivo de esta entrada del blog. El objetivo era, única y exclusivamente, contaros que se puede hacer y daros unas indicaciones básicas de cómo lograrlo; abriros un poco el apetito y de paso, publicar algo de lo que estamos haciendo internamente en Plain Concepts.

¡Espero que os haya sido de utilidad! Keep Rockin’!

Rock Tip:

Allá por 1973 Lynyrd Skynyrd publicaron su primer disco, su gran debut, “pronounced 'lĕh-'nérd 'skin-'nérd”; este disco incluía temazos como el Simple Man (para mi una de las mejores canciones de toda la historia… así de simple ;)) y el Free Bird, recientemente revitalizado gracias al Guitar Hero.

En aquel álbum aparecía también el tema que protagoniza el rock tip de este articulo; Gimme Three Steps. En realidad, la historia que cuenta esta canción no tiene mucho que ver con este artículo; esos tres pasos de los que habla la canción son los que le pide una chica a su captor para escapar corriendo de él. La letra es muy buena, espectacular, pero yo hago una reinterpretación y me quedo con los tres simples pasos que necesitamos para montar nuestro servidor de símbolos mediante symstore.

Bueno chicos, este fue el rock tip de hoy… ya veis que tengo el día sureño! :)

Posted: 15/4/2009 10:05 por Pablo Alvarez | con 2 comment(s) |
Archivado en: ,
Comparte este post:

Comentarios

Octavio Hernández ha opinado:

Pablito,

As always, outstanding post!

Y coincido al 100% en que tanto "Simple Man" como "Free Bird" son temas inmortales del rock.

Abrazo - Octavio

# April 15, 2009 3:27 PM

Pablo Alvarez ha opinado:

Buff, Octavio!! que se me paso responderte! :)

Gracias por el comentario :) Un abrazote!

# June 8, 2009 4:26 PM