2009-03-07 15 views
23

Ho appena saputo che ci sono punti di interruzione dati. Ho lavorato negli ultimi 5 anni in C++ utilizzando Visual Studio e non ho mai utilizzato i punti di interruzione dei dati.Cosa sono i punti di interruzione dei dati?

Qualcuno può far luce su quali sono i punti di interruzione dei dati, quando usarli e come utilizzare con VS?

Secondo la mia comprensione, possiamo impostare un punto di interruzione dei dati quando vogliamo verificare le modifiche al valore di una variabile. In questo caso, possiamo impostare un breakpoint di dati con una condizione sul valore della variabile.

Altri esempi?

risposta

28

Definizione:

punti di interruzione di dati consentono di rompere l'esecuzione quando il valore memorizzato in un determinato cambia posizione di memoria.

Da MSDN: How to: Set a Data Breakpoint:

Come impostare una modifica alla memoria Breakpoint

  1. Dal menu Debug, scegliere Nuovo punto di interruzione e fare clic su New Data punto di interruzione

    -o -

    nei punti di interruzione wi ndow Menu, fare clic sul nuovo menu a discesa e selezionare Nuovo punto di interruzione dati.

    Viene visualizzata la finestra di dialogo Nuovo punto di interruzione.

  2. Nella casella Indirizzo, immettere un indirizzo di memoria o un'espressione che restituisce un indirizzo di memoria. Ad esempio, & foo da interrompere quando cambia il contenuto della variabile foo.

  3. Nella casella Numero di byte, immettere il numero di byte che si desidera che il debugger guardi. Ad esempio, se si inserisce 4, il debugger guarderà i quattro byte a partire da & foo e interromperà se uno di questi byte modificherà il valore.

  4. Fare clic su OK.

0

ritengo punti di interruzione di dati sono i punti di interruzione che si verificano quando una parte viene impostata su un certo valore. Ad esempio, è possibile impostare un punto di interruzione quando i == 10 in un ciclo tipico da interrompere dopo la decima iterazione. È inoltre possibile controllare le modifiche alle variabili nell'heap, ad esempio attendere che un membro di una classe venga modificato.

+2

La prima frase è errata - se si imposta un punto di interruzione per visualizzare un valore previsto che è un "punto di controllo". La tua ultima frase è corretta. –

52

Il buon vecchio' Daniel LeCheminant has a solid answer su ciò un punto di interruzione di dati fa, quindi mi lancio in alcuni aneddoti che evidenziano impieghi utili:

Qualsiasi scenario in cui si sa che cosa cambierà, ma hanno poca o nessuna idea dove il codice che lo cambia vive (altrimenti si potrebbe semplicemente utilizzare un punto di interruzione condizionale).In particolare,

scenari "impossibili" - programma si blocca, perché variabile X è NULL, quando la variabile X dovrebbe mai essere NULL perché nessun codice da nessuna parte mai imposta variabile X-NULL. Inserire un punto di interruzione normale nel codice che inizializza X e, quando viene colpito, impostare un punto di interruzione dati per controllare la modifica su NULL. Un po 'più comune è il caso in cui la memoria viene rilasciata troppo presto, e ci sono ancora dei suggerimenti su di esso in giro: usa i punti di interruzione dei dati per scoprire chi sta liberando la memoria.

Scenari noiosi - una libreria di terze parti sta facendo cose cattive, cattive, orribili alle strutture dati. Sai che sta accadendo, perché qualcuno sta cestinando i tuoi dati e ovviamente il tuo codice è perfetto. Ma tu non sai dove, o quando. Certo, potresti passare da un megabyte di DLL disassemblate ... ma perché preoccuparti, quando puoi impostare un punto di interruzione dei dati sui tuoi dati, sederti e aspettare che venga spazzato via!

Heisenbugs - simile allo scenario impossibile, ma se ne vanno quando si guarda troppo da vicino, in modo tale che i punti di interruzione normali, anche quelli condizionali, siano inutili. Il tempo e la logica sensibile di input dell'utente sono particolarmente vulnerabili a questo genere di cose. Dal momento che i punti di interruzione dei dati non richiedono il debugger in realtà fino a l'ora è giusta, partendo dal presupposto che si può trovare una posizione di memoria che cambierà solo quando si verifica effettivamente quel bug inafferrabile è possibile utilizzare i punti di interruzione dei dati per impostare una trappola per l'Heisenbug e prenderlo in flagrante delicto.

scenari spaghetti - comuni nei vecchi, basi di codice marci in cui i dati globali si accede ovunque. Sì, potresti usare i normali breakpoint condizionali ... ma ne avresti bisogno a centinaia. I punti di interruzione dei dati lo rendono facile.

3

Finora abbiamo una grande definizione e una serie di grandi spiegazioni teoriche.

Facciamo un esempio concreto!

Attualmente sto lavorando su un codebase piuttosto grande e contorto. Ho apportato una piccola modifica sicura a un bit di codice e ho iniziato a recuperare - in un blocco completamente indipendente del codebase - i crash nell'allocatore di memoria. Questo è generalmente un segno che stai facendo qualcosa di molto sbagliato con la gestione della memoria - cancellazione doppia o scrittura fuori limite.

Per fortuna, abbiamo un'opzione per attivare un gestore di memoria di debug che controlla cose come questa. L'ho acceso e ha immediatamente iniziato a segnalare una violazione della guardia di blocco della memoria, il che significa che qualcosa ha scritto fuori limite. Il problema è che questo rapporto si presenta solo una volta che la memoria è stata deallocata, essenzialmente dicendo "hey, qualcosa di è stato risolto in. Spero tu possa capire cosa!"

Sfortunatamente questo particolare frammento di memoria, nel punto di deallocation, è completamente indistinguibile da letteralmente migliaia di altri pezzi di memoria. Fortunatamente, il nostro framework di debug contrassegna ogni allocazione con un ID consecutivo e la memoria che è stata danneggiata aveva un ID coerente (# 9667, se siete curiosi.) Un breakpoint rapido nel gestore della memoria in seguito e sono riuscito a trovare dove la memoria è stata allocata. Il che, come risultò, non fu immediatamente d'aiuto.

Ma a quel punto, ho avuto diversi componenti importanti:

  • sapevo l'indirizzo di un blocco di memoria
  • Sapevo che la durata prevista di quella memoria
  • sapevo che, a un certo punto nel futuro, un byte specifico oltre la durata prevista di quella memoria verrebbe sovrascritto

Dato ciò, potrei impostare un dato punto di interruzione su quel byte specifico, quindi premere "vai" e scoprire dove si è verificata la corruzione.

Ciò che ho fatto - ha portato a un errore fuori-da-uno che sono ora in fase di riparazione.

E questo è un esempio concreto di come i punti di interruzione dei dati possono essere utili. :)

Problemi correlati