Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: bonmario - Febbraio 22, 2012, 08:56:30 am

Titolo: Monitorare una variabile in debug
Inserito da: bonmario - Febbraio 22, 2012, 08:56:30 am
Ciao a tutti,
con il debug di Lazarus è possibile monitorare il valore di una variabile facendo in modo che il debug si fermi quando tale variabile viene modificata?
Ho provato a guardare in giro ma non ho capito se col DBG si può fare o no.

Grazie in anticipo, Mario
Titolo: Re:Monitorare una variabile in debug
Inserito da: xinyiman - Febbraio 22, 2012, 09:01:54 am
Non penso anche se ti dico che non ne sono sicuro. Io so che il debug funziona con il concetto del breackpoint ma non so se segnala anche il cambio del valore di una variabile!
Titolo: Re:Monitorare una variabile in debug
Inserito da: mmxngg - Febbraio 22, 2012, 09:28:48 am
Ti posizioni sulla variabile e premi shift+F5 (o tasto destro, debug -> add watch point). Ti apre un menù dove puoi mettergli praticamente qualsiasi condizione che attiva o meno il breakpoint (supporta anche le espressioni).
Titolo: Re:Monitorare una variabile in debug
Inserito da: xinyiman - Febbraio 22, 2012, 09:57:34 am
Buono a sapersi!  ;D
Titolo: Re:Monitorare una variabile in debug
Inserito da: bonmario - Febbraio 22, 2012, 12:07:37 pm
Ci ho provato, ma non ho capito come funziona.
Ho creato un progetto nuovo e ci ho messo un bottone. Ho aggiunto questo codice:
Codice: [Seleziona]
procedure TForm1.Button1Click(Sender: TObject);
var Idx:Integer;
begin
  for Idx:=1 to 10 do begin
    Form1.Caption:=IntToStr(Idx);
  end;
end;

Sono andato col cursore sotto la variabile Idx ed ho premuto Shift + F5 ed ho compilato i parametri come nell'immagine allegata.
Nella videatina delle watch la mia riga rimane sempre "Disabled".

Il mio scopo è quello di fare in modo che il debug, nel momento in cui la variabile Idx cambia valore, si fermi sulla riga che ha provocato questo cambio di valore.

Ciao, Mario
Titolo: Re:Monitorare una variabile in debug
Inserito da: mmxngg - Febbraio 22, 2012, 02:35:41 pm
In pratica a te serve un breakpoint a livello globale e non semplicemente condizionato. Sinceramente non avevo mai provato perchè di solito mi bastava il secondo caso o addirittura un breakpoint semplice senza alcuna condizione. La risposta è NI, puoi farlo  ::)

In pratica funziona solo ed esclusivamente sulle variabili che non sono all'interno di una classe o che non sono a livello locale (e fin qui ok). Il tuo caso non può funzionare perchè Idx è locale ed è memorizzata nello stack che non ha un indirizzo di memoria ben definito nel momento in cui assegni il breakpoint (questo mi sa che non lo fa nessun ambiente di sviluppo). Non funziona (e dovrebbe) quando le variabili sono all'interno di una classe...probabilmente non è in grado di risalire correttamente all'indirizzo in memoria (è un bug). In pratica devi dichiarare la variabile dopo l'implementation e li aggiungere il breakpoint.

P.S.

Se all'interno delle watch la riga è disabled la devi attivare premendo sulla lampadina, se è corretta ti appare la scritta Valid altrimenti Invalid (Idx è Invalid, una variabile in una classe risulta Valid ma non si blocca...).

Quando si attiva ottieni una videata di questo tipo (notare che entrambe le variabili sono Enabled ma solo una funziona...vabbè).

(http://s15.postimage.org/w7mkld7c7/Immagine.jpg) (http://postimage.org/image/w7mkld7c7/)
Titolo: Re:Monitorare una variabile in debug
Inserito da: bonmario - Febbraio 22, 2012, 06:40:39 pm
Grazie !!!
Stasera non ho tempo, ma domani ci riprovo al lavoro.

Toglimi una curiosità: per come dichiari "Pippo", non dovrebbe essere una "Var"?
Io di solito dichiaro le var come hai fatto tu. le const le dichiaro in questo modo:

const CstColNomeFile=0;

La dichiarazione così come l'hai fatta tu di una const non l'ho mai vista !!!!!!

Ciao, Mario
Titolo: Re:Monitorare una variabile in debug
Inserito da: mmxngg - Febbraio 22, 2012, 07:26:45 pm
Premessa : utilizzo Lazarus da meno di 3 settimane quindi vado a logica secondo gli altri linguaggi.

Dichiarando Pippo come Const Pippo = 0 crei una semplice dichiarazione di un valore assoluto (un alias) che non è assegnato a nessun indirizzo di memoria, con l'altro sistema crei una variabile e gli assegni un valore iniziale (una costante e non un alias). Tanto per dirne una, con il primo metodo non potresti utilizzare il breakpoint o utilizzare la costante in una routine dichiarata così :

procedure Test(var Qualcosa: Integer);

Questo perchè la routine Test potrebbe modificare la variabile Qualcosa e ha bisogno di un indirizzo reale. In sostanza dipende che ci devi fare, se è realmente una costante che non verrà mai variata allora è preferibile il primo metodo, altrimenti il secondo (cambia il modo con cui il compilatore tratta il dato).

Poi magari ho detto delle cazzate e in quel caso significa che Lazarus tratta il dato come variant (pessima cosa...quindi spero di no).