2016-06-25 15 views
1

Delphi XE5/32, unter Windows10/64, generiert Win32 VCL ausführbar.Startfehler während der Hauptformularerstellung

Ich erhalte zeitweise Zugriffsverletzungsfehler, die mit der Formularerstellung verknüpft sind. Dieser Fehler wurde auch selten von einigen Endbenutzern festgestellt (ich bin derzeit in kleinen Versuchen mit einer Testgruppe von etwa 20 Benutzern).

Das geht seit Monaten und bis vor kurzem wurden meine Versuche, das Problem zu finden, durch die Tatsache frustriert, dass es so schwer zu reproduzieren war. Nun konnte ich aber endlich eine Umgebung etablieren, die den Fehler recht zuverlässig reproduziert. Überraschenderweise habe ich festgestellt, dass bestimmte E-Mails in meinem Google Mail-Konto im Chrome-Browser angezeigt werden. Die E-Mails, die das Problem verursachen, sind vollständig konsistent - siehe das Video in https://www.devexpress.com/Support/Center/Question/Details/T395896. (Ich habe diese Abfrage ursprünglich an das DevExpress-Supportforum gesendet, weil ich eine der Komponenten als Ursache vermutet habe, aber jetzt bezweifle ich das).

Ich habe jetzt meinen Splash-Screen vorübergehend deaktiviert und meine vorherigen automatisch erstellten Datamodule, die im OnCreate des Hauptformulars erstellt werden, geändert. Die DPR ist jetzt sehr einfach:

begin 
Application.Initialize; 
Application.MainFormOnTaskbar := True; 
Application.Title := 'Topshare V3'; 
Application.CreateForm(TMainForm, MainForm); 
Application.Run; 
end. 

Das heißt, passiert nichts vor dem Create für das Hauptformular Programm.

Wenn der Fehler auftritt, hängt das Programm entweder still während Application.CreateForm (TMainForm, MainForm) und bevor OnCreate des Hauptformulars aufgerufen wird; oder es endet vor OnCreate und ruft OnDestroy des Formulars auf. Das Problem tritt also beim Analysieren des DFM auf.

Wenn ich das Programm im Debug-Modus in der IDE Schritt, wenn der Fehler aktiv ist, gibt es mehrere AVs während Application.CreateForm (TMainForm, MainForm) ausgelöst. Diese sind nur aus der IDE ersichtlich, also vermutlich innerhalb von try..except blocks. Wenn ich Pause auf der dieser ersten klicken, wird der Call Stack in der Regel so etwas wie:

System.SysGetMem(???) 
:00405423 SysGetMem + $43 
System.Classes.TReader.ReadComponent(nil) 
System.Classes.TReader.ReadDataInner(???) 
System.Classes.TReader.ReadData($7BCCD90) 
System.Classes.TComponent.ReadState(???) 
Vcl.Controls.TControl.ReadState($9C6F098) 
Vcl.Controls.TWinControl.ReadState($9C6F098) 
:00aa0bcd TcxCustomGrid.ReadState + $29 
System.Classes.TReader.ReadDataInner(???) 
System.Classes.TReader.ReadData($7BF4230) 
System.Classes.TComponent.ReadState(???) 
Vcl.Controls.TControl.ReadState($9C6F098) 
Vcl.Controls.TWinControl.ReadState($9C6F098) 
System.Classes.TReader.ReadComponent(nil) 
System.Classes.TReader.ReadDataInner(???) 
System.Classes.TReader.ReadData($7BF3F50) 
System.Classes.TComponent.ReadState(???) 
Vcl.Controls.TControl.ReadState($9C6F098) 
Vcl.Controls.TWinControl.ReadState($9C6F098) 
System.Classes.TReader.ReadComponent(nil) 
System.Classes.TReader.ReadDataInner(???) 
System.Classes.TReader.ReadData($9B9C7A0) 
System.Classes.TComponent.ReadState(???) 
Vcl.Controls.TControl.ReadState($9C6F098) 
Vcl.Controls.TWinControl.ReadState($9C6F098) 
Vcl.Forms.TCustomForm.ReadState($9C6F098) 
System.Classes.TReader.ReadRootComponent($9B9C7A0) 
System.Classes.TStream.ReadComponent($9B9C7A0) 
System.Classes.InternalReadComponentRes(???,???,$9B9C7A0) 
System.Classes.InitComponent(TMainForm) 
System.Classes.InitInheritedComponent($9B9C7A0,TForm) 
Vcl.Forms.TCustomForm.Create(???) 
Vcl.Forms.TApplication.CreateForm(???,(no value)) 
TopshareV3.TopshareV3 

Die scheinbare Beteiligung von SysGetMem mich zu dieser Frage führen: Delphi XE5 Acces Violation on app start

Dementsprechend habe ich aktiviert beide Bereichsüberprüfung und Überlauf Überprüfung, aber das hilft nicht.

Es muss etwas mit dem DFM nicht stimmen.

Ein Aspekt ist, dass das Hauptformular von einem Vorgängerformtyp erbt. Das Vorfahren-Formular enthält keine Komponenten, nur einige Methoden. Der Quellcode des Vorgängerformulars enthält nicht die globale Standardvariablendeklaration. So ist die Form Erklärung Hauptform ist: TMainForm = class (TAbase)

und die DFM enthält: geerbt Mainform: TMainForm

Das Formular mehrere verschachtelte Frames enthält, und verwendet auch mehrere ActionManagers, ActionToolbars, eine ActionMainMenubar, eine PopupActionbar und ein dxSkinController.

Kann jemand noch mehr Licht auf was zu suchen, oder wie weiter?

EDIT: Der oben gezeigte Call-Stack ist nach dem ersten AV. Aber ich habe die von Ihnen vorgeschlagene Verfolgung bereits durchgeführt. Ich habe einen Haltepunkt in System.Classes in Zeile # 10169, in TReader.ReadComponent. Ich füge dann Uhren auf "Parent.name" und "CompName" hinzu. Dann, beginnend wieder in der IDE, sehe ich die verschiedenen Hauptformkomponenten, die erstellt werden.

Früher, als die Datamodule zuerst erstellt wurden, würde ich sehen, eine Reihe von Komponenten erstellt, aber die AV würde immer passieren, nachdem der Haltepunkt mit Uhren die erste Ansicht des ersten cxGrid (DevExpress) zeigt. Wenn ich dem Formular (und dem ersten zu erstellenden Fenster) ein zusätzliches Raster hinzugefügt habe, ohne dass Eigenschaften festgelegt wurden, scheint das neue Raster den AV auszulösen. Mit anderen Worten, es schien, als wäre das cxGrid das Problem - daher mein Kontakt mit DevExpress-Unterstützung.

Aber die Erstellung der Datamodule zu verschieben und meinen Begrüßungsbildschirm zu entfernen, hat die Dinge geändert (obwohl der AV immer noch auftritt). Jetzt geht es weit über das erste Raster hinaus; und, obwohl ein cxGrid immer noch involviert zu sein scheint, bin ich mir nicht sicher, ob das jetzt relevant ist (ich habe viele Gitter im Hauptformular).

EDIT: In der IDE laufen, gibt es 3 AVs (wenn ich fortfahren nach jedem) - dann hängt das Programm, bevor mein Code in OnCreate ausgeführt: der erste ist $ C0000005 mit der Nachricht 'Zugriffsverletzung bei 0x0040541d: Lesen von Adresse 0x002d001c '; und, zweimal, $ C0000005 mit der Nachricht 'Zugriffsverletzung bei 0x00a8107a: Lesen der Adresse 0x00000068'.

BEARBEITEN: Mein anfänglicher Haltepunkt bei Klassen # 10169 wird nun einige Dutzend Mal ausgeführt, während die Formularkomponenten aus dem DFM verarbeitet werden. Auf der jetzt kritischen Komponente (immer noch eine cxGrid-Ansicht) führt die Ausführung von Klassen # 10169 (in Treader.ReadComponent) zu CreateComponent # 10114 zu Result.create # 10129. Von hier aus gibt es eine Schleife (oder Rekursion), die einen Assembler-Block enthält, der bei System # 16752 beginnt, und ein leeres Tobject.Create bei # 15511. Ein Haltepunkt bei System # 15511 wird 29 Mal ausgeführt. Dann das 30. Mal durch, das AV tritt bei System # 16757 auf, CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance

EDIT: Wenn Schritt durch Ausführung ausgeführt wird, wenn es keine Fehlerbedingung gibt, scheinen die Dinge im Wesentlichen die gleichen wie wenn dort ist: das ist die gleiche Folge von Anrufen. Die gleiche Sequenz, die in dem obigen Paragraphen beschrieben wird, scheint zu folgen - außer für keinen AV am 30. Pass oder danach.

+1

Was ist die genaue Nachricht, die Sie in der AV sehen, einschließlich der Speicheradressen? Ich kann kaum glauben, dass es eine Korrelation zwischen * bestimmten E-Mails gibt, die in Chrome * und dem AV angezeigt werden. Tritt dies auch bei der Anzeige dieser E-Mails und einer neuen, leeren VCL-Formularanwendung auf? Oder eine neue VCL-Formularanwendung mit einem Hauptformular, das keinen Code oder Steuerelemente enthält, die von derselben Basisform erben? Ich denke, dass Sie auch außerhalb der Basis sind, wenn SysGetMem beteiligt ist; Ich denke, das Problem ist vor diesem Punkt und wird nur in SysGetMem wegen Speicherbeschädigungen vor dann ausgelöst. –

+0

(Fortsetzung) Ich basiere das auf 'System.Classes.TReader.ReadComponent (nil)' 'davor - unter welchen Umständen würden Sie erwarten ReadComponent mit einem Argument von' nil' aufgerufen werden? Passt irgendetwas in Ihrer Hauptform an irgendetwas im Datamodul (z. B. ein datensensitives Steuerelement)? Normalerweise muss das Datenmodul vor dem Hauptformular im .dpr erstellt werden. Die Zuweisung von TApplication.MainForm wird nicht beeinflusst, da ein Datenmodul kein Hauptformular sein kann. –

+0

Welche Antivirensoftware verwenden Sie und erhalten Sie immer noch das Verhalten, wenn Sie es ausschalten? Ich habe in letzter Zeit ein ähnliches Problem festgestellt, das dadurch behoben wurde, dass ich mein Delphi-Projektverzeichnis von der Stelle, an der der AV-Monitor läuft, ausgeschlossen habe. – MartynA

Antwort

1

Ich habe das Problem auf DevExpress dxSpreadSheetCore Einheit eingegrenzt. Wenn ich das in eine Uses-Klausel einfüge, wird der Fehler angezeigt. wenn ich es weglasse, kein Fehler. Ich habe das Problem bei DevExpress eingereicht, obwohl ich meine Anwendung nicht ausreichend vereinfachen konnte, um ihnen auch eine nützliche Demonstration des Fehlers zu geben.

Meine Annahme, basierend auf Kommentaren hier, ist, dass etwas im Initialisierungsabschnitt von dxSpreadSheetCore (oder in seinen abhängigen Einheiten) Heap-Beschädigung verursacht.

+0

Dies ist keine Antwort auf die Frage, die Sie gestellt haben. Es ist eher ein * Ich vermute, dass diese Komponente von Drittanbietern das Problem verursacht, also habe ich es ihnen gesagt, aber ich kann keine Beweise oder eine Lösung liefern. * Kommentar. Sie können dies leicht bestätigen, indem Sie eine neue, leere VCL-Formularanwendung erstellen (Datei-> Neu-> VCL-Formularanwendung), die Einheit dxSpreadSheetCore zur uses-Klausel hinzufügen und die Anwendung ausführen. Tritt das gleiche Problem auf? Wenn ja, haben Sie das Problem für DevEx reproduziert. Wenn nicht, haben Sie das Problem nicht erkannt. Viel wahrscheinlicher ist letzteres der Fall. –

+0

Nein, eine einfache Anwendung hat den Fehler nicht gezeigt. Denken Sie jedoch daran, dass das zuverlässige Ermitteln des Fehlers nur unter bestimmten Umständen möglich war, bei denen andere Anwendungen gleichzeitig auf einem bestimmten System ausgeführt wurden. Ich hasse es, das Schicksal herauszufordern, indem ich es sage, aber das Problem ist weg, seit ich diese Veränderung vorgenommen habe. –

Verwandte Themen