Crear puntos de ruptura en tiempo de ejecución con .NET

Punto de ruptura (Breakpoint)Todos sabemos crear puntos de ruptura (breakpoints) desde Visual Studio, y lo indispensables que resultan para depurar nuestras aplicaciones. Y si la cosa está complicada, los puntos de ruptura condicionales pueden ayudarnos a lanzar el depurador justo cuando se cumpla la expresión que indiquemos.

Lo que no conocía era la posibilidad de establecerlos por código desde la propia aplicación que estamos depurando, que puede resultar útil en momentos en que nos sea incómodo crearlos desde el entorno de desarrollo. Es tan sencillo como incluir el siguiente fragmento en el punto donde deseemos que la ejecución de detenga y salte el entorno:


// C#
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}

' VB.NET:
If System.Diagnostics.Debugger.IsAttached Then
System.Diagnostics.Debugger.Break()
End If


Como ya habréis adivinado, el if lo único que hace es asegurar que la aplicación se esté ejecutando enlazada a un depurador, o lo que es lo mismo, desde dentro del entorno de desarrollo; si se ejecuta fuera del IDE no ocurrirá nada.

Si eliminamos esta protección, la llamada a Debugger.Break() desde fuera del entorno generará un cuadro de diálogo que dará la oportunidad al usuario de abrir el depurador:

Ventana que posibilita la depuración de una aplicación .NET

De todas formas lo mejor es usarlo con precaución, que eso de dejar el código con residuos de la depuración no parece muy elegante...

Publicado en: www.variablenotfound.com.

Published 23/9/2008 21:22 por José M. Aguilar
Comparte este post:
http://geeks.ms/blogs/jmaguilar/archive/2008/09/23/crear-puntos-de-ruptura-en-tiempo-de-ejecuci-243-n-con-net.aspx

Comentarios

# re: Crear puntos de ruptura en tiempo de ejecución con .NET

Hola,

la linea if (System.Diagnostics.Debugger.IsAttached) no es necesaria.

Si ejecutamos "System.Diagnostics.Debugger.Break();" sin estar en el IDE, si es una versión de debug, nos aparecerá una ventana para seleccionar un "depurador". Con esto, podemos hacer el attach del ejecutable al IDE y depurar.

Esto resulta muy util para proyectos que son dificilmente arrancables desde el IDE. Por ejemplo, servicios, HttpModules, etc.

Un saludo.

Wednesday, September 24, 2008 1:50 PM por Javier

# re: Crear puntos de ruptura en tiempo de ejecución con .NET

Correcto, Javier. La línea sólo es necesaria si deseamos prevenir la aparición de este cuadro.

Y efectivamente, puede resultar útil también en esos casos.

Gracias por aportar!

Wednesday, September 24, 2008 2:04 PM por José M. Aguilar

# re: Crear puntos de ruptura en tiempo de ejecución con .NET

Yo lo uso con frecuncia.

Además en mis depuraciones de bugs recurro a otro método de clase para el modo release que muestra la pila de llamadas, y agrego a un objeto global un mensjae de error. Todo "like this":

   Public Sub MostrarError(ByRef MiError As Object, Optional ByRef Source As Object = Nothing, Optional ByRef sDescripAmpliada As String = "")

       Dim sMensaje As String = ""

       Dim sFuente As String = ""

       Dim sPilaLlamadas As String = ""

       If TypeOf MiError Is ErrObject Then

           sMensaje = "Error: " & MiError.Number.ToString & vbCrLf & "Descripción: " & Err.Description & vbCrLf & "Origen en: " & MiError.Source & vbCrLf & "Invocando desde: " & TypeName(Source) & vbCrLf

           Try

               If Not Source Is Nothing Then sFuente = TypeName(Source)

           Catch ex As Exception

           End Try

       ElseIf TypeOf MiError Is Exception Then

           Dim oExcep As Exception = MiError

           Try

               sFuente = oExcep.Source

           Catch ex As Exception

           End Try

           sMensaje = "Error: " & oExcep.Message & vbCrLf & "Origen en: " & sFuente & vbCrLf & "Invocando desde: " & sFuente & vbCrLf

       End If

       sMensaje &= " " & sDescripAmpliada

       Try

           sPilaLlamadas = My.Application.Info.StackTrace

       Catch ex As Exception

       End Try

       sMensaje &= vbCrLf & " Pila de llamadas: " & sPilaLlamadas

       If InStr(sFuente, "cl") = 1 Then 'si es una clase invocamos a metodo que eleve evento de incidencia

           Try

               Source.ElevarIncidencia(Replace(sMensaje, vbCrLf, "#sep#"), sFuente)

           Catch ex As Exception

           End Try

       End If

       'agregamos a pila de errores accesible desde aplicación y librerías

       SyncLock goErrores

           goErrores.Add(sMensaje & vbCrLf & sFuente)

       End SyncLock

       If System.Environment.UserInteractive = True Then

           'es una aplicación con interfaz de usuario: aplicación de escritorio

           MsgBox(sMensaje, , sFuente)

       Else

           Try

               'es un aplicación sin interfaz de usuario; un servicio, etc.

               'intenamos elevar por la pila una expcepcion

               Throw New Exception(Replace(sMensaje, vbCrLf, " "))

           Catch ex As Exception

               'no es atrapada desde ningun sitio de la pila, continuamos como podamos

           End Try

       End If

   End Sub

Thursday, September 25, 2008 12:07 PM por Julio Trujillo Leon

# re: Crear puntos de ruptura en tiempo de ejecución con .NET

Apunto y corrijo, excusen estoy aprendiendo y todos los tips son interesantes. Gracias

Thursday, September 25, 2008 10:27 PM por Turcios Pita