![]() |
Automatische Problem-Erkennung
Moin zusammen.
Wir hatten heute einen Fehler gefunden, der nicht sofort ersichtlich ist.
Delphi-Quellcode:
Hier wird in DoMore die Variable FMyVal übergeben und da sVal in DoSomething als const deklariert ist,
...
type TWhatever = class(TForm) public Procedure DoSomething(const sVal : String); Procedure DoMore(); private FMyVal : String; end; ... procedure TWhatever.DoMore(); begin DoSomeThing(FMyVal); end; procedure TWhatever.DoSomething(const sVal : String); begin FMyVal := ''; if (sVal = 'bla') then Close(); end; ... erstellt Delphi hier keine Kopie, sondern arbeitet auf dem Original. Jetzt nehme ich aber in der ersten Zeile ihm das Original unter dem Arsch weg. Das führt zu Speicherfehlern und dann random irgendwo zu Zugriffsverletzungen. Lösung hier: "const" weg nehmen, so dass Delphi für sVal eine Kopie anlegt. Frage: Gibt es eine (automatisierbare) Möglichkeit solche Konstellationen zu erkennen? Ich würde gerne ausschließen, dass wir solche Fehler irgendwo vertseckt haben und ich weiß nicht, wie ich sowas suchen kann. Selbst wenn das Problem nicht mehr erkannt werden kann, wenn Funktionen andere Funktionen aufrufen, die dann den Ursprungswert modifizieren. Dieser Fehler beunruhigt mich nun doch schon etwas. Und da jetzt "überall" etwas zu bauen, dass beim Funktionsaufruf den Speicher schützt und entsprechende Exceptions wirft, wenn dieser doch bearbeitet wird, würde zudem ewig dauern und Ressourcen und Performance fressen. Vielleicht hat da ja jemand eine Idee zu. Liebe Grüße Incocnito |
AW: Automatische Problem-Erkennung
Kurz gesagt ist der Fehler, innerhalb der Klasse ein Feld als Parameter zu übergeben. Vermutlich könnte man das prüfen lassen, aber es könnte manchmal auch Absicht sein.
|
AW: Automatische Problem-Erkennung
Noch schöner:
Delphi-Quellcode:
Da der Speicherbereich erneut verwendet wird, ist in sVal der neue Wert direkt drin.
begin
FMyVal := '42'; DoMore; end; procedure TWhatever.DoMore(); begin DoSomeThing(FMyVal); end; procedure TWhatever.DoSomething(const sVal : String); begin FMyVal := ''; FMyVal := '43'; if (sVal = '43') then ShowMessage('Aua'); end; Das ist wirklich eine schöne Falle, die man nicht sofort sieht. |
AW: Automatische Problem-Erkennung
Mir ist gerade ein bisschen Schwarz vor Augen geworden. Ein Glück dass ich kein Freund von Const-Parametern bin.
Ich werde trotzdem mal nach Const in Parametern suchen und mir alle Übergaben ansehen. |
AW: Automatische Problem-Erkennung
Zitat:
"#10#13" random in der lokalen Variable (sVal) bei einem Testlauf. Also kann da bei solch einer Konstellation auch Speichermüll drin stehen. Es muss nicht sein, dass er den aktuellen Wert der Hauptvariable übernimmt. Das war bei dir vielleicht nur Zufall (oder es liegt daran, dass du eine andere Delphi-Version hast). Liebe Grüße Incocnito |
AW: Automatische Problem-Erkennung
ByReference-Parameter.
Ich lasse zu oft gern das CONST weg, weil es hässlich aussieht. Ich hab solche Probleme also fast nie. :lol: Ohne CONST gibt es im String ein RefCount+1, womit es in der Funktion zwei Variablen sind, beim := wird es ordentlich aufgelöst und somit wird nichts überschrieben. Ein
Delphi-Quellcode:
hätte dieses Problem nicht, da es in den Speicher eines Registers passt und somit keine Referenz genutzt wird (obwohl man denkt das befohlen zu haben),
const Val: Integer
aber darum hat Emba vor 'nem Weilchen das
Delphi-Quellcode:
erfunden, damit man auch dort dieses Fehlerchen bewundern darf. :party:
const [Ref] Val: Integer
|
AW: Automatische Problem-Erkennung
Zitat:
|
AW: Automatische Problem-Erkennung
Eine ungünstige Klassenstruktur könnte solche Fehler begünstigen.
Wenn man sich des Problems bewusst ist, lässt sich das auch vermeiden:
Delphi-Quellcode:
procedure TWhatever.DoMore();
begin DoSomeThing(Copy(FMyVal)); end; |
AW: Automatische Problem-Erkennung
Zitat:
Bei Delphi 7 kann ich das so produzieren, aber bei Delphi 11 kann ich hier kein Problem oder Absturz reproduzieren. |
AW: Automatische Problem-Erkennung
Nach Delphi 7 wurde der neue Speichermanager eingeführt. Ich hatte mit Delphi 11 getestet.
Abstürzen tut da nichts, aber der geänderte Speicherinhalt ist direkt zu sehen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz