Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Fehlertoleranz DELPHI Compiler (https://www.delphipraxis.net/171828-fehlertoleranz-delphi-compiler.html)

bernhard_LA 27. Nov 2012 10:22

Fehlertoleranz DELPHI Compiler
 
Anbei mal ein simples Codebeispiel mit einem Fatalen Bug

Delphi-Quellcode:

   TDataClass = class (...)

          .....

   end;



  TForm1 = class(TForm)

       
       aDataClass : TDataClass;

  end;



  TForm2 = class(TForm)

       
       bDataClass : TDataClass;

  end;



procedure aForm1.Doit (....);
begin


    try
    aForm2.Create(...)
   
    aDataClass := aForm2.bdataclass; //  gemeinsame Daten :-)
 
    finally
    aForm2.Free
    end;


    aDataClass.Auswerten(...);

end;

aDataClass.Auswerten(...); ist je eigentlich nil nachdem ich aForm2.Free
ausgeführt habe. Trotzdem ging bei mir der Aufruf oft gut ( .... >> 100 x ), vermutlich war der Speicher noch nicht überschrieben , aber halt nicht immer.
Den Fehler haben wir erst nach langer Suche entdeckt, weil der Code ja eigentlich gemacht hat was er sollte und dort hat niemend einen Fehler mehr vermutet.

Kann ich mein Projekt so coompilieren eine strenge Speicherverwaltung erzwingen damit solche Fehler schnell auffallen ?

himitsu 27. Nov 2012 10:27

AW: Fehlertoleranz DELPHI Compiler
 
obj.Free setzt nicht auf nil ... es gibt nur frei.
Delphi-Referenz durchsuchenFreeAndNil

Und das obj.Create ist theoretisch auch korrekt (wenn man es richtig nutzt) ... es initialisiert aber nur eine bestehende Instanz und reserviert keinen Speicher.

Patito 27. Nov 2012 10:52

AW: Fehlertoleranz DELPHI Compiler
 
Zitat:

Zitat von bernhard_LA (Beitrag 1193177)
Anbei mal ein simples Codebeispiel mit einem Fatalen Bug

Kann ich mein Projekt so coompilieren eine strenge Speicherverwaltung erzwingen damit solche Fehler schnell auffallen ?

Für sowas ist ein Speichermanager im Debug-Modus da. -> FastMM - FullDebugMode

Der Speichermanager kann dann z.B. beim Freigeben den Speicher mit einem speziellen Muster überschrieben, und
kriegt dann damit später mit wenn der Prozess versucht auf diesen Speicher zuzugreifen.

Solche Tools gehören eigentlich zum Standard wenn man seine Software vernünftig Testen will.

stahli 27. Nov 2012 10:56

AW: Fehlertoleranz DELPHI Compiler
 
@Bernhard

Ein Bug ist es nicht, eher ein konzeptionelles Problem.
Hier (und an anderen Stellen) wurde das schon mal diskutiert: http://www.delphipraxis.net/159095-r...e-objekte.html

Das neu eingeführte Referenzcounting für Objekte (siehe aktueller Thread) könnte evtl. etwas Abhilfe schaffen. Allerdings würde dann das Objekt noch im Speicher bleiben, obwohl es eigentlich bereits aufgelöst sein sollte. Im Grunde würde das Überschreiben des Speichers verhindern und Deine "Glückstreffer" sicher gestalten.
Es würde also nicht "knallen", aber Du würdst mit einem Objekt arbeiten, das eigentlich gar nicht mehr da ist.

Um den Verweis zu nilen braucht es irgendeinen Observer, der standardmäßig im Delphi leider nicht existiert.

bernhard_LA 27. Nov 2012 11:10

AW: Fehlertoleranz DELPHI Compiler
 
@ Stali :
mit eigentlich ungültigen Werte noch arbeiten zu können halte ich für nicht sehr geschickt, man sollte das Problem an der Wurzel packen und auch dort sofort beheben.




FASTMM4 und Madshi können zwar nach dem Auftreten solle Probleme anzeigen, ich fände es aber eine bessere Lösung wenn mann beim Übersetzen auf solche "Handwerklichen" Fehler den Code zu untersuchen könnte

himitsu 27. Nov 2012 11:13

AW: Fehlertoleranz DELPHI Compiler
 
Und das der Aufruf "zufällig" gut geht liegt daran,

daß der Objekt-Zeiger auf einen Speicher zeigt, wo ein passendes Objekt mal war.
Außerdem gibt FastMM Speicher nicht immer sofort wieder frei.
Es scheint sonst noch niemand zwischenzeitlich in diese Speicherblöcke reingeschrieben zu haben.
Und "vorallem" du machst in deinen "billigen" Objekten nicht viel ... vorallem nicht im Donstructor und Destructor, sonst hätte das falsche Create bei dir auch schon geknallt.

Zitat:

mit eigentlich ungültigen Werte noch arbeiten zu können halte ich für nicht sehr geschickt,
Man kann FastMM so einstellen, daß es Speicher "zerstört", also mit "ungültigen" Werten überschreibt, nachdem er freigegeben wurde.
Wenn dann so der Speicher der Objekte wirklich weg ist, dann knallt es eher mal.

[edit]
Daß obj.Create bei dir zufällig funktioniert, lag wohl eher daran, daß du hier eine böse globale Variable nutzt, welche mit nil initialisiert war.

Sir Rufo 27. Nov 2012 11:20

AW: Fehlertoleranz DELPHI Compiler
 
Zitat:

Zitat von bernhard_LA (Beitrag 1193188)
@ Stali :
mit eigentlich ungültigen Werte noch arbeiten zu können halte ich für nicht sehr geschickt, man sollte das Problem an der Wurzel packen und auch dort sofort beheben.

FASTMM4 und Madshi können zwar nach dem Auftreten solle Probleme anzeigen, ich fände es aber eine bessere Lösung wenn mann beim Übersetzen auf solche "Handwerklichen" Fehler den Code zu untersuchen könnte

Ist das jetzt der Ruf nach "Betreutem Programmieren"?

Wie lange soll denn der Compiler auf dem Code rumnudeln bis er alle möglichen handwerklichen Fehler gefunden hat?

Das ist ein klarer Fall für einen Test mit DUnit aber nicht für den Compiler

Patito 27. Nov 2012 11:23

AW: Fehlertoleranz DELPHI Compiler
 
Zitat:

Zitat von bernhard_LA (Beitrag 1193188)
FASTMM4 und Madshi können zwar nach dem Auftreten solle Probleme anzeigen, ich fände es aber eine bessere Lösung wenn mann beim Übersetzen auf solche "Handwerklichen" Fehler den Code zu untersuchen könnte

Ein Syntax-Check entspräche in etwa der Lösung eines NP-Vollständigen Problems (mit entsprechend endloser Rechenzeit), oder der Check funktioniert eben nur "manchmal".

Mit FastMM findet man rein praktisch 99.99% aller Probleme. Was willst Du mehr?

stahli 27. Nov 2012 11:51

AW: Fehlertoleranz DELPHI Compiler
 
Zitat:

Zitat von bernhard_LA (Beitrag 1193188)
@ Stahli :
mit eigentlich ungültigen Werte noch arbeiten zu können halte ich für nicht sehr geschickt, man sollte das Problem an der Wurzel packen und auch dort sofort beheben.

Das Problem liegt halt in der EDV.
Wenn ein Dritter mein Fahrrad klaut kann ich mich am nächsten Tag nicht mehr drauf setzen.

Wenn irgendwer mein Objekt zerstört, dann sind die Speicherzellen halt ja noch dort und irgendwelche Zeiger können auf die Stelle verweisen.
Eine vollständig automatische Zeigerbereinigung ist undenkbar - nicht mal für mich! :stupid:

Aber wenn ich dem Compiler sagen könnte: "Richte mal für mich eine Überwachung meines Fahrrades ein und setze F1 und F2 auf null, wenn das Fahrrad aufgelöst wird.", das wäre schon eine nette Sache und würde dem Programmierer eigene Obser-Lösungen oftmals abnehmen können.
Natürlich hilft das Konstrukt auch nur dann, wenn das Fahrrad regulär freigegeben wird, aber nicht, wenn eine Walze drüber fährt (bzw. der Speicher irgendwie fehlerhaft überschrieben wird).

Stevie 27. Nov 2012 12:00

AW: Fehlertoleranz DELPHI Compiler
 
Klassischer Fall von Objekt über seine lifetime hinaus benutzt.

Will man dem entgehen, muss man entweder genau Herr darüber sein, wann wer was frei gibt oder man wendet sich einer GC Sprache zu, da kann man anders rumfuhrwerken.

In deinem konkreten Fall würde ich aber eher ein Architektur Problem vermuten, da dein TForm2 das TDataClass Objekt erzeugt, während TForm1 das scheinbar nicht macht. Wenn doch, dann hast du an der gezeigten Stelle nicht nur einen dangling Pointer sondern auch ein Memory leak. An dieser Stelle steht dann die Entscheidung, ob du exakt dieselbe Instanz brauchst, oder ob dort ein Assign Aufruf reicht, um bloß den State von dem einen TDataClass Objekt ins andere zu schieben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:46 Uhr.
Seite 1 von 5  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz