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.

4 comentarios sobre “Crear puntos de ruptura en tiempo de ejecución con .NET”

  1. 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.

  2. 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!

  3. 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

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *