Freitag, 23. Juni 2017

Delphi hat einen Fehler...?

(Oder wie verbringe ich einen halben Tag mit Fehlannahmen...)

Klar, nicht nur einen, aber so ist das eben mit Software...


Da es keine fehlerfreie Software gibt, kann man diese Frage getrost mit ja beantworten. Aber wie suchen "wir" den Fehler?

Natürlich am besten mit Unit-Tests... Aber UI? OK...Ein anderes Thema

Workflow:

<F9> Testen -> Exception

Exception position ist nicht im eigenen Source, sondern tief in der RTL. Auch noch in einen Assembler-Teil.

OK - Kann nur die Liste nicht initialisiert sein...

Also Breakpoint setzen und nochmal...
<F9> Testen -> Debugger hält brav am Breakpoint an...

FListe in die Watchvariablen übernehmen... Nöö geht nicht... Und dann fängt es an falsch zu laufen...

1. Fehlannahme : OMG, Die IDE kann schon wieder eine Variable nicht anzeigen...

also fix ne lokale Variable "LListe" und mit der arbeiten...

<F9> Testen -> Debugger hält brav am Breakpoint an...
<F7>, <F7>,<F7> - Prima alles richtig... <F7> FListe := LListe;
Bang - Exception;

OK - Logger anwerfen... Geht ja dank FDK mit einer Zeile...

Das Log sieht gut aus... Oberflächlich betrachten... Alles wird schön erzeugt.... Alles Prima!

Aber:
<F9> Testen -> Debugger hält brav am Breakpoint an...
<F7>, <F7>,<F7> - Prima alles richtig... <F7> FListe := LListe;
Bang - Exception;

2. Fehlannahme : Shit, ich Idiot, greife von einem Thread aus auf eine Liste in der Klasse zu...

FListe ist kein Object, aber

kein Thema Uses Delphiprofi.FDK.Classes;

Class -> Class(TClassWithSync) // Erzeugt eine FSync : TObject für einen TMonitor...

TMonitor.Enter(FSync);
try
  FListe := LListe;
finally
  TMonitor.Exit(FSync);
end;

Jetzt aber....Breakpoint auf die Zuweisung...

<F9> Testen - Exception... What... Der ist gar nicht bis zum BreakPoint gekommen... Nochmal durch steppen...

<F9> Testen - <F7>, <F7>,<F7> - Prima alles richtig... <F7> TMonitor.Enter(FSync) - Bang...
Exception...

Das gibt es doch gar nicht, ich bin doch lokal in der Klasse wieso kann er nicht auf FSync zugreifen...

3. Fehlannahme : Ich habe einen Fehler in 10.2 gefunden... Ich kann aus einem Thread nicht mehr auf private Felder eine einer Klasse zugreifen...(Kaum zu glauben, ist aber so {nicht})

Also das Ganze mit 10.1

<F9> usw... Bang... gleicher Fehler...

Das ist jetzt aber doof... Also schnell den Browser mit dem "System Dashboard" wieder zu machen...

OK.. Dann mal ohne Thread...

Ups... Jetzt geht es... Wieso das den?

Also wieder mit Thread - Am Thread kann es auf keinen Fall liegen, das mache ich immer so... erstmal ein Paar Logeinträge mehr erzeugen...

<F9> Log... Bla, Bla Bla... TMainViewModel.BeforeDestruction - WTF... Wer war das.... Ist doch kein Interface... Also kein Problem mit dem REFCount... Hätte ich doch besser mein MVVM-Framework genommen, aber nein für so einen kleine App...

Breakpoint setzen...
 
Wird von der MainView aufgerufen mit FreeAndNIL(FViewModel) aber wieso?

Wer lesen kann ist klar im Vorteil... Finde den Fehler...

procedure TFormMain.FormDeactivate(Sender: TObject);
begin
  FreeAndNIL(FViewModel);
end;

Das kommt davon, wenn man auf die schnelle mit der IDE etwas zusammen klicken will... Einfach eine Zeile zu hoch im Objektinspektor....

procedure TFormMain.FormDestroy(Sender: TObject);
begin
  FreeAndNIL(FViewModel);
end;

Wäre besser gewesen...

Ohne den gelernten Workflow -> Ich sehe meinen Fehler nicht - muss am Delphi liegen... Was leider hin und wieder mal vor kommt... Wäre das nicht passiert...

Logisch - und um es richtig zu stellen...
Natürlich geht es jetzt auch mit 10.2 und aus dem Thread...

Kaum macht man es richtig, schon funktioniert es...