¿Cuáles son los puntos de interrupción de datos?

Acabo de llegar a saber que hay puntos de interrupción de datos . He trabajado durante los últimos 5 años en C ++ usando Visual Studio, y nunca he usado puntos de interrupción de datos.

¿Puede alguien arrojar algo de luz sobre qué son los puntos de quiebre de datos, cuándo usarlos y cómo usarlos con VS?

Según mi entendimiento, podemos establecer un punto de interrupción de datos cuando queremos verificar cambios en el valor de una variable. En este caso, podemos establecer un punto de interrupción de datos con una condición en el valor de la variable.

¿Algún otro ejemplo?

Definición:

Los puntos de corte de datos le permiten interrumpir la ejecución cuando cambia el valor almacenado en una ubicación de memoria especificada.

Desde MSDN: Cómo: Establecer un punto de interrupción de datos :

Cómo establecer un punto de cambio de memoria

  1. Desde el menú Depurar, elija Nuevo punto de interrupción y haga clic en Nuevo punto de interrupción de datos

    -o-

    en el menú de la ventana Puntos de interrupción, haga clic en el menú desplegable Nuevo y elija Nuevo punto de interrupción de datos.

    Aparece el cuadro de diálogo Nuevo punto de interrupción.

  2. En el cuadro Dirección, ingrese una dirección o expresión de memoria que evalúa a una dirección de memoria. Por ejemplo, & foo para romper cuando los contenidos de la variable foo cambian.

  3. En el cuadro Conteo de bytes, ingrese la cantidad de bytes que desea que vea el depurador. Por ejemplo, si ingresa 4, el depurador observará los cuatro bytes que comienzan en & foo y dividirá si alguno de esos bytes cambia de valor.

  4. Haga clic en Aceptar.

El buen ol ‘ Daniel LeCheminant tiene una respuesta sólida sobre lo que hace un punto de quiebre de datos, así que incluiré algunas anécdotas que resaltan usos útiles:

Cualquier escenario en el que sepa qué cambiará, pero tiene poca o ninguna idea de dónde vive el código que lo cambia (ya que de lo contrario podría simplemente usar un punto de interrupción condicional). Específicamente,

Escenarios “imposibles” : el progtwig se bloquea, porque la variable X es NULL , cuando la variable X nunca debe ser NULL porque ningún código en ningún lugar alguna vez establece la variable X en NULL . Coloque un punto de interrupción normal en el código que inicializa X , y cuando se golpea, configure un punto de interrupción de datos para observar el cambio a NULL . Algo más común es el caso en que la memoria se libera demasiado pronto , y todavía hay indicadores de que está dando vueltas: use puntos de interrupción de datos para descubrir quién está liberando la memoria.

Escenarios tediosos : una biblioteca de terceros está haciendo cosas malas, horribles y horribles en sus estructuras de datos. Sabes que está sucediendo, porque alguien está destruyendo tus datos y obviamente tu código es perfecto. Pero no sabes dónde ni cuándo. Claro, podrías pasar por un megabyte de DLL desensamblado … pero ¿por qué molestarse, cuando puedes establecer un punto de interrupción de datos en tus datos, relajarte y esperar a que se destruya?

Heisenbugs : similar al escenario imposible, pero desaparecen cuando se observa demasiado de cerca, de modo que los puntos de corte normales, incluso los puntos de interrupción condicionales, son inútiles. La lógica sensible a la sincronización y al usuario es particularmente vulnerable a este tipo de cosas. Dado que los puntos de corte de datos no requieren que el depurador realmente se rompa hasta que sea el momento adecuado , suponiendo que se puede encontrar una ubicación de memoria que solo cambiará cuando se presente ese error difícil de usar, puede usar puntos de interrupción de datos para establecer una trampa para el Heisenbug y atraparlo en flagrante delito .

Escenarios de espagueti : comunes en las antiguas bases de código podridas donde se accede a los datos globales en todas partes . Sí, podrías usar puntos de interrupción condicionales simples … pero necesitarías cientos de ellos. Los puntos de interrupción de datos lo hacen fácil.

Hasta ahora tenemos una gran definición y un montón de grandes explicaciones teóricas.

¡Tengamos un ejemplo concreto!

Actualmente estoy trabajando en una base de código bastante grande y complicada. Hice un pequeño cambio seguro en un bit de código y comencé a obtener, en un fragmento de la base de código completamente no relacionado, lockings en el asignador de memoria. En general, esto es una señal de que está haciendo algo muy incorrecto con la gestión de la memoria: eliminación doble o escritura fuera de límites.

Afortunadamente, tenemos la opción de activar un administrador de memoria de depuración que comprueba cosas como esta. Lo encendí e inmediatamente comenzó a informar una violación de guardia de bloque de memoria, lo que significa que algo escribió fuera de los límites. El problema es que este informe aparece solo una vez que se desasigna la memoria, básicamente diciendo “hey, algo se rompió. ¡Espero que puedas descubrir qué!”

Lamentablemente, este trozo particular de memoria, en el punto de desasignación, es completamente indistinguible de literalmente miles de otros trozos de memoria. Afortunadamente, nuestro marco de depuración etiqueta cada asignación con una identificación consecutiva, y la memoria que se corrompió tenía una identificación constante (# 9667, si tiene curiosidad). Un punto de interrupción rápido en el administrador de memoria más tarde y pude encontrar dónde memoria fue asignada. Lo cual, como se vio después, tampoco fue inmediatamente útil.

Pero en ese punto, tenía varios componentes importantes:

  • Sabía la dirección de un bloque de memoria
  • Sabía la duración prevista de esa memoria
  • Sabía que, en algún momento en el futuro , se sobrescribiría un byte específico más allá de la duración prevista de esa memoria

Dado esto, podría establecer un punto de interrupción de datos en ese byte específico, luego presionar “ir” y descubrir dónde ocurrió la corrupción.

Lo cual hice – condujo a un error de “uno por uno” que ahora estoy en proceso de corregir.

Y ese es un ejemplo concreto de cómo los puntos de interrupción de datos pueden ser útiles. 🙂

Creo que los puntos de interrupción de datos son puntos de interrupción que ocurrirán cuando cierta memoria se establezca en un cierto valor. Por ejemplo, puede establecer un punto de interrupción cuando i == 10 en un ciclo for típico para detener después de la décima iteración. También puede ver los cambios en las variables en el montón, como esperar a que se modifique un miembro de una clase.