Inicio > .NET Framework, Apunte, C# > C# 101: símbolos de depuración

C# 101: símbolos de depuración


En un proyecto estándar generado por Visual Studio, existen dos tipos de configuraciones básicas: Debug y Release. La primera, Debug, suele definir opciones que permiten al compilador generar información sobre el programa: variables, información sobre objetos y clases, etc. Esta información la solemos referir como símbolos de depuración.

Generar los símbolos de depuración son necesarios, pues los depuradores los leen para poder presentar la información al programador durante, digamos, un breakpoint. El programa compila a código binario (o MSIL, en el caso de .NET) y por tanto es imposible saber si quiera el nombre de las variables. Los símbolos de depuración ayudan al depurador con esto. Incluso, esta información permite realizar enlazado de objetos incrementales, reduciendo considerablemente el tiempo de compilación y generación del ensamblado.

Ahora bien, todos los símbolos de depuración se almacenan en una base de datos, llamada Program Database (PDB). Este archivillo, que puedes encontrar en el directorio de salida con la extensión PDB, es de hecho una base de datos que puede ser abierta con el motor SQL Server Compact Edition (i.e. puedes usar el SQL Server Management Studio).

El depurador, que es quien usa el PDB, lo carga al momento de iniciar una sesión. Lo busca en el directorio donde se encuentra el EXE. La parte importante es que el depurador revisa que coincida, a nivel binario, todo lo que dice el PDB con el ejecutable mismo. Si no coinciden, el PDB no es cargado. Si el PDB no existe, el Visual Studio nos presenta una ventana para que escojamos el directorio donde se encuentra. Esto último es importante, pues nos permite cargar símbolos que se encuentren en otras ubicaciones.

Hay un escenario en particular donde esto es útil, y lo ilustraré con una anécdota personal. Cuando desarrollamos nuestras aplicaciones, usualmente llega el momento de pasarlas a algún servidor de Q&A, antes del Go Live. Ahí, los clientes suelen realizar sus pruebas. En esta ocasión, el sistema estuvo jalando bastante bien, hasta que en una ocasión un usuario logró hacer tronar la aplicación bajo ciertas condiciones. Rápidamente nos reportó el problema.

Pues resultó que no pudimos duplicar el problema en nuestro ambiente de desarrollo. Estuvimos tres días intentándolo, copiando las características del servidor de Q&A. Nada. Funcionaba a la perfección. Hasta intentamos ver que el problema no estuviera "entre la silla y el teclado". Nada. Los logs y traces de poca ayuda fueron.

Desafortunadamente, la fecha para la liberación del sistema se acercaba peligrosamente, así que no nos quedó de otra: solicitamos permiso para instalar el Visual Studio en el servidor de Q&A para de ahí ejecutar el programa y ver qué sucedía. Naturalmente, nos mandaron a freír espárragos: no sólo necesitaban autorización del corporativo, la cuál tardaría mínimo un mes, sino que no estaba permitido instalar programas en los servidores de Q&A, y que el hacerlo provocaría que nos impidieran el paso a producción, pues ellos no podrían certificar que la app funcionara bien.

En fin, tras varias reuniones y alegatos, propusimos que se hiciera todo de forma remota: a final de cuentas, el Visual Studio podía conectarse de forma remota. Sin embargo, les dijimos, necesitamos que coloquen el archivo PDB… y ardió Troya: que no, no se podía alterar el ambiente de Q&A, yada yada yada. En fin, terminamos generando el PDB y gracias a esta opción de seleccionar el archivo, pudimos conectarnos de forma remota con el PDB en nuestro equipo local. De esta forma encontramos que era el Directorio Activo quien daba un timeout, y pudimos solucionar el problema.

Un truco antes de partir

Bueno, esta entrada ha sido más informativa que otra cosa. Pero voy a dejar un pequeño truco antes de concluirlo, para que no te vayas en cero.

Cuando depuramos un programa, podemos ver el valor de las variables de tipo de dato en las ventanas de Quick Watch del Visual Studio.

clip_image001

Ahora bien, esto funciona padre para tipos de datos simples como int, bool o string. ¿Qué pasa con tipos de datos complejos, como un DataTable? ¿Qué pasa con las clases que nosotros creamos?

Si ves la imagen anterior, en el caso del DataTable muestra este valor: {Length=1}. Es decir, que el DataTable explícitamente indica que el valor que interesa es el valor de la propiedad Length. ¿Cómo puedo hacer esto para mis clases?

Este es el truco: para hacer esto, tenemos que utilizar la clase DebuggerDisplayAttribute, en el espacio de nombres System.Diagnostics. En este atributo, al constructor le pasamos una cadena de texto con un formato sobre cómo va a mostrarse el valor. Por ejemplo:

[DebuggerDisplay("Length = {Length}")]
class MyClass
{
    public int Length { get; set; }
}

Y eso es suficiente. Con esto, aparecerá una cadena de texto donde el texto entre llaves se reemplaza por el valor del elemento: miembro o propiedad, cuyo nombre corresponda con el nombre entre las llaves.

Y este es el truco. Puedes revisar la documentación de DebuggerDisplayAttribute para mayor información.

Categorías:.NET Framework, Apunte, C# Etiquetas: , ,
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s