Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Sporadische Zugriffsverletzungen (https://www.delphipraxis.net/196843-sporadische-zugriffsverletzungen.html)

Hobbycoder 25. Jun 2018 08:28

Sporadische Zugriffsverletzungen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi,

ich brüte schon das ganze WE über einen Fehler, wo ich augenscheinlich sporadisch Zugriffsverletzungen bekomme. Das debuggen mit MadExcept führte bisher zu keinem Ergebnis, da mir dort Code-Zeilennummern ausgegeben werden, die gar nicht existieren.

Zu dem Programm: Ich möchte mir ein kleinen Inventarisierungsprogramm schreiben. Alles soll in einem Virtualstringtree dargestellt werden. Ich habe das ganze über Klassen aufgebaut, z. TServer, TPrinter, TPasswort, usw. welche selbst jeweils in einer TObjectList gehalten werden.
Da ich alle Klassen dann aber in einer VST darstellen möchte, habe ich mir eine HelperKlasse geschrieben, welche jeweils den Klassennamen und den Objektzeiger enthält. Darüber baue ich dann die VST auf. (Sicherlich hat dieses Konzept möglicherweise Schwächen, aber die möchte ich hier jetzt nicht diskutieren. Vielleicht nach dem ich den Fehler gefunden habe).

Mein Problem ist jetzt, dass manchmal beim Neuaufbau der VST, manchmal beim Laden der Daten und manchmal beim Beenden der Application eine Zugriffsverletzung auftritt, und das ohne Veränderung der Daten, deren Ursprung ich nicht ermitteln kann. Vielleicht mag einer sich das mal anschauen und mir auf die Spur bringen. Danke

Anbei der Source und die Beispieldaten.

TiGü 25. Jun 2018 09:35

AW: Sporadische Zugriffsverletzungen
 
Wenn du das Testprojekt ohne die spezielle Komponente TBadgeBtn hochladen kannst, so das es sozusagen out-of-the-box zu kompilieren ist, kann man dir bestimmt weiterhelfen. :thumb:

Hobbycoder 25. Jun 2018 09:49

AW: Sporadische Zugriffsverletzungen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Oh, ja sorry. Hier das Projekt mit Standardbuttons. Jedi's und VST hab ich drin gelassen. Jedi's werden wohl die meisten haben. Und ohne VST macht's keinen Sinn.

TiGü 25. Jun 2018 10:05

AW: Sporadische Zugriffsverletzungen
 
Auch wenn da ganz viel im Argen ist, konzentrieren wir uns mal auf das Wesentliche.

Schließe das Speicherleck in
Delphi-Quellcode:
TfrmMain.NeuKunde
.
Du erzeugst
Delphi-Quellcode:
k:=TKunde.Create;
, gibst aber nur frei, wenn der Kunde schon existiert.
Es würde wohl reichen, wenn du am Schluss einfach
Delphi-Quellcode:
Kunden.Add(K)
aufrufen würdest.
Dann kannst du dir das
Delphi-Quellcode:
Kunden.LoadFromDirector(DataBaseDir);
auch sparen.

Hobbycoder 25. Jun 2018 18:40

AW: Sporadische Zugriffsverletzungen
 
Okay, da habe ich vergessen, k wieder freizugeben, oder aber eben Tkunden.Add(k) und mir das Load sparen.
Gibt sicherlich auch bessere Varianten, das zu lösen. Wo nun aber ganz viel im Argen ist, kann ich so nicht nachvollziehen.

Leider hat das auch nichts mit dem Problem zu tun, da die Zugriffsverletzung auch ohne hinzufügen eines neuen Kunden kommt. Aber halt eben nicht immer.
Mein Fehler muss irgendwo zwischen dem Erzeugen der Nodes und dem GetText liegen, denn wenn ich beide Proceduren durchsteppe kommt der Fehler nach BuildList und vor GetText.

Klaus01 26. Jun 2018 09:01

AW: Sporadische Zugriffsverletzungen
 
.. auch wenn ich mich jetzt unbeliebt mache..
Wo sind die Unit-Tests?

Grüße
Klaus

TiGü 26. Jun 2018 09:20

AW: Sporadische Zugriffsverletzungen
 
Welche Version des Virtual Treeviews verwendest du denn eigentlich genau?
Kannst du bspw. in der Unit VirtualTrees.pas in der Konstante VTVersion sehen (um die Zeile 100 herum).

jaenicke 26. Jun 2018 09:43

AW: Sporadische Zugriffsverletzungen
 
Zitat:

Zitat von Hobbycoder (Beitrag 1405777)
Mein Fehler muss irgendwo zwischen dem Erzeugen der Nodes und dem GetText liegen, denn wenn ich beide Proceduren durchsteppe kommt der Fehler nach BuildList und vor GetText.

Wie sieht denn der Stacktrace an der Stelle aus?

Hobbycoder 26. Jun 2018 10:13

AW: Sporadische Zugriffsverletzungen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von TiGü (Beitrag 1405828)
Welche Version des Virtual Treeviews verwendest du denn eigentlich genau?
Kannst du bspw. in der Unit VirtualTrees.pas in der Konstante VTVersion sehen (um die Zeile 100 herum).

VTVersion = '6.6.0';

Zitat:

Zitat von jaenicke (Beitrag 1405831)
Zitat:

Zitat von Hobbycoder (Beitrag 1405777)
Mein Fehler muss irgendwo zwischen dem Erzeugen der Nodes und dem GetText liegen, denn wenn ich beide Proceduren durchsteppe kommt der Fehler nach BuildList und vor GetText.

Wie sieht denn der Stacktrace an der Stelle aus?

Siehe Screenshots im Anhang. Zu Beachten sei an dieser Stelle im Screenshot MadExcept2.png die Zeilennummern, die bei der Unit u_daten ausgegeben werden. Diese u_daten hat gar nicht so viele Zeilen.

MadExcept1.pnp tritt auf, wenn ich vom aus der ersten Ansicht, wo im Treeview lediglich die Kundendaten stehen, einen Eintrag mittels NodeDblClick öffne und die Detaildaten angezeigt werden sollen. Übergehe ich den Fehler, so läuft das Prog ohne Fehler weiter und auch alle danach erzeugen Nodes sind alle wie gewünscht vorhanden.

MadExcept2.pnp tritt auf, wenn ich dann das Programm beenden will.

TiGü 26. Jun 2018 15:00

AW: Sporadische Zugriffsverletzungen
 
Zitat:

Zitat von Hobbycoder (Beitrag 1405837)
Siehe Screenshots im Anhang. Zu Beachten sei an dieser Stelle im Screenshot MadExcept2.png die Zeilennummern, die bei der Unit u_daten ausgegeben werden. Diese u_daten hat gar nicht so viele Zeilen.

Da steht zwar u_daten und Zeile 6703, aber die Funktion ist klar angegeben mit der Notify-Methode der generischen Liste. Und darauf bezieht sich auch die Zeilennummer.
Du wirst wahrscheinlich ein Objekt haben, was aber schon freigegeben ist - warum gilt es zu untersuchen - und noch als Dangling Pointer in der Liste steckt.
Das Freigeben über den Listenautomatismus oder die Erzeugung von Virtual Nodes aus diesem kaputten Objekt führt dann bei dir dann zu Problemen.

Übrigens kannst du auch ganz wunderbar sowas schreiben:

Delphi-Quellcode:
if MyObject is TPassword then


anstatt

Delphi-Quellcode:
if MyObject.Classname = TPassword.Classname then

Luckie 26. Jun 2018 15:17

AW: Sporadische Zugriffsverletzungen
 
Was Allgemeines. So sporadische Zugriffsverletzungen deuten drauf hin, dass was mit dem Speicher nicht stimmt. Beispielsweise wurde ein Objekt freigegeben, auf das dann aber noch zugegriffen wird. Manchmal hat man Glück und die Speicherstelle enthält noch gültige Daten, aber manchmal eben auch nicht und dann kommt es zu einer Zugriffsverletzung. Also untersuche dein Code mal auf solche Situationen hin.

p80286 26. Jun 2018 20:17

AW: Sporadische Zugriffsverletzungen
 
Jetzt fehlt noch der Hinweis auf Bereichsprüfung und Konsorten und die Basis für die Fehlersuche ist gelegt.

Gruß
K-H

Ralf Kaiser 27. Jun 2018 06:04

AW: Sporadische Zugriffsverletzungen
 
Zitat:

Zitat von Luckie (Beitrag 1405874)
Beispielsweise wurde ein Objekt freigegeben, auf das dann aber noch zugegriffen wird. Manchmal hat man Glück und die Speicherstelle enthält noch gültige Daten...

Was den Fehler dann um so schwerer lokalisierbar macht. Wenn z.B. durch Zufall auf dem Entwicklungsrechner immer genug Speicher vorhanden ist und darum der Speicher an der Stelle noch nicht überschrieben wurde taucht der Fehler unter Umständen gar nicht auf. Beim Benutzer, wo eine andere Speichersituation vorliegt knallt es dann sofort.

In einer solchen Situation kann man eigentlich nur mit FastMM im "FullDebug"-Modus einem solchen Problem auf die Spur kommen. Da gibt es die Möglichkeit den Speicher freigegebener Objekte mit einem Bit-Muster überschreiben zu lassen, was dann in dieser Situation das Auffinden des Problems enorm erleichtert. Da knallt es nämlich direkt beim nächsten Zugriff und man sieht im Debugger sofort wo der ungültige Zugriff erfolgte.

Hobbycoder 27. Jun 2018 09:12

AW: Sporadische Zugriffsverletzungen
 
Danke für eure zahlreichen Hinweise und Lösungsvorschläge. Ich werde mal versuchen damit dem Fehler auf die Spur zu kommen.
Bis hier hin erst mal vielen Dank.

freimatz 27. Jun 2018 09:53

AW: Sporadische Zugriffsverletzungen
 
Zitat:

Zitat von Ralf Kaiser (Beitrag 1405913)
In einer solchen Situation kann man eigentlich nur mit FastMM im "FullDebug"-Modus einem solchen Problem auf die Spur kommen.

Da der TE MadExcept erwähnt, die Option "instantly crash on bufffer ..." wäre auch noch eine Möglichkeit. (basic settings)

jaenicke 27. Jun 2018 10:27

AW: Sporadische Zugriffsverletzungen
 
Mit FastMM bekomme ich direkt beim Editieren Fehler mit Stacktrace vom Erstellen und Freigeben des fehlerhaften Objekt.

Blup 27. Jun 2018 10:34

AW: Sporadische Zugriffsverletzungen
 
Im OnClick-Event der Speedbutton wird indirekt SetView aufgerufen.
Darin werden alle Speedbutton freigegeben.
Nachdem dieses OnClick-Event abgearbeitet ist, kehrt das Programm zum nun nicht mehr existierenden Speedbutton zurück.
Die Methode, welche das OnClick-Event aufgerufen hat, wird zuende geführt.
Der Zeiger Self ist ungültig und verweist auf Speicher der vorher mit den Daten des Speedbutton belegt war.
Dort können jetzt ganz andere Daten liegen, die bei Schreibzugriffen beschädigt werden.

Lösung 1:
Man verzichtet auf das Erzeugen und Freigeben der Buttons und macht diese nur sichtbar oder unsichtbar.

Lösung 2:
Im OnClick-Event wird nur eine Nachricht an das Formular gepostet(PostMessage) und die Methode sofort beendet.
Die eigentliche Verarbeitung erfogt dann als Reaktion auf den Empfang der Nachricht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:00 Uhr.

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