Announcement

Collapse
No announcement yet.

Zugriffsverletzung "EAccessViolation" bei Programmende

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zugriffsverletzung "EAccessViolation" bei Programmende

    Hallo,

    jedesmal wenn ich mein Programm beende erhalte ich eine Zugriffsverletzung "EAccess Violation" Zugriffsverletzung, "...Vorgang read konnte auf Speicher nicht ausgeführt werden..." anscheinend wird ein Objekt nicht freigegeben oder existiert nicht mehr, ich verwende mehrere Module, wie kann ich jetzt rausfinden welches Objekt nicht freigeben wird bzw. wo die Anwendung noch einen read Befehl beim Programmende durchführt um den Fehler zu beseitigen?

    Vielen Dank und Grüße Hendrik

  • #2
    1, Schreib die Adresse die dir gemeldet ist auf.

    2, Starte dein Programm in der Delphi-IDE (gleiches Codebasis wie Programm welches Absturz mit Fehler produziert hat)

    3, Wähle Menüpunkt "Suchen/Laufzeitfehler suchen" und gibt dort die Adresse hast. Delphi-IDE springt an die Stelle des verursachenden Codes. Falls Du glück hast siehst Du Pascal-Code. Falls nicht nur Assembler-code.

    Evtl. ist es von Vorteil wenn du Debug-Infos als auch Debug-DCU's verwendest

    Comment


    • #3
      Hallo Bernhard,

      Dein Tip mit dem Laufzeitfehler ist recht interessant. Bei mir sehe ich jedoch leider nur Assembler-Code.

      Wie kann ich Pascal-Code sehen ? Geht das mit den Debug-Infos oder Debug-DCU's, die Du erwähnt hast ?

      Grüsse,
      Carste

      Comment


      • #4
        Hallo Carsten,

        das hab' ich einem anderen Posting 'provoziert', als ich ahnungsloser BCB-ler, den CodeGuard zur Auffindung eines solchen Laufzeitproblems empfohlen habe: <BR>
        <I>CodeGuard kenn ich nicht, aber man kann sich kostenlos MemProof downloaden. Das ist ein nützliches Teil, das u.a. Speicherlecks meldet.</I> <BR>

        Vielleicht wäre das ja auch was für Dein Problem...

        Grüße Joche

        Comment


        • #5
          Falls Du nur Assembler-Code siehst wäre folgender Test noch interessant:

          Start Anwendung, gehe zu Speicheradresse und setze Breakpoint drauf. Wenn er (hoffentlich nur beim Beenden) an diese stelle gelangt bekommst Du evtl. den Aufrufstack und kommst dann in Delphi Code

          Comment


          • #6
            Hallo,

            bei mir trat der Fehler gestern im Zusammenhang mit der "Report Builder"-Komponente auf. Zuerst lief das Programm einwandfrei, doch nach einer Zeit immer die EAccessViolation-Exception.

            Der Fehler trat beim Versuch auf, einen bereits auf dem Bildschirm angezeigten Report auszudrucken.

            Ich habe daraufhin gestern den Report nicht mehr über den Befehl "ppReport1.Template.LoadFromFile" geladen, sondern fest im Programm implementiert.

            Daraufhin ist der Fehler verschwunden. Heute habe ich testweise noch mal wieder den Befehl eingefügt, aber ich konnte den Fehler nicht reproduzieren. Ich vermute nun, daß der Fehler dadurch zustande kommt, daß ich kein Reset des Printers durchgeführt habe und irgendwann der Speicher zu ist. Aber das wollte ich jetzt aus Zeitgründen nicht mehr erforschen.

            @ Jochen:
            Das mit MemProof hört sich gut an. Werde ich mir mal downloaden und in Zukunft dran denken, es zu benutzen.

            @ Bernhard:
            Auch diesen Tip werde ich in Zukunft versuchen, nachzuvollziehen.

            Grüsse,
            Carste

            Comment


            • #7
              Hallo,

              ich habe jetzt wieder mal einen neuen Speicherfehler bei Programmende in einem anderen Programm gehabt.
              <PRE>
              Exception EAccessViolation bei 00234193.
              Zugriffsverletzung bei Adresse 00634193.
              Lesen von Adresse 012B2AD0.
              </PRE>

              Diese 3 Adressen wollte ich nun über "Delphi\Start Anwendung" testen. Die ersten beiden Adressen führen beide zur folgenden Codezeile des DatenModul:
              <PRE>
              procedure TDM.DatabaseAfterDisconnect(Sender: TObject);
              begin
              Form1.label1.Caption:= 'DB-Verbindung nicht aktiv';
              end;
              </PRE>

              Die 3. Adresse führte mich nur zu Assembler-Code (auch nach Setzen auf Breakpoint).

              Meine Frage nun. Warum werden 3 Adressen angegeben ? Kann mir jemand dies verständlicher ausführen, warum dies so ist ?

              Durch das "FormCloseQuery"-Ereignis und dem Code konnte ich den Fehler nun beheben.
              <PRE>
              DM.Database.Connected:= False;
              </PRE>

              @Jochen:
              Ich habe den Fehler noch einmal provoziert, um zu sehen, wie ich mit MemProof den Fehler finde.
              Nach dem Beenden meines Programms ist allerdings "MemProof" im Fenster "Debug Window" abgestürzt. Er hat immer wieder die Exception "Zugriffsverletzung bei Adresse 00634193" ausgegeben, welches der 2. Adresse des obigen Beispiels entspricht. Wie kann ich nun mit MemProof entdecken, welche Quellcodezeile für die Exception verantwortlich ist ?

              Grüsse,
              Carste

              Comment


              • #8
                Hallo Carsten,

                diesen Fehler hatte ich auch mal, das wenn ein Datenbankverbindung auch noch beim Programmende aktiv ist, eine Exception auftritt.

                Das Problem das ich letztendlich gefunden hatte war, das beim Beenden der DB-Verbindung erst beim Programmende auf das Screen-Objekt zugegriffen wird (um einen Cursor zu setzen), jedoch dieses Objekt schon zerstört wurde.

                Also Grundsätzlich früher schließen (z.B. in FormCloseQuery

                Comment


                • #9
                  Hallo Carsten,

                  leider kenn ich mich mit Delphi und MemProof nicht aus, da ich aus dem BCB Lager stamme... Ich weiß nur, daß das MemProof das Delphi Äquivalent zum CodeGuard im C++ Builder ist.

                  Ist es möglich, daß Form1 schon aus dem Speicher entfernt wurde, oder gerade entfernt wird, wenn das Label aktualisiert werden soll?

                  In C++ würde ich das entweder in try... catch setzen, oder überprüfen, ob das Form überhaupt noch existiert, oder ob es gerade 'destroyed' wird:
                  <PRE>
                  if (Form1 != NULL) // Form existiert noch
                  {
                  if (Form1->ComponentState.Contains(csDestroying) == false)) // wird auch nicht gerade gelöscht
                  Form1->Label1->Caption = "DB-Verbindung nicht aktiv";
                  }
                  </PRE>
                  Eventuell hilft aber auch ein Application.ProcessMessages, direkt nach dem Setzen des Labels (ganz großes eventuell).

                  Grüße Joche

                  Comment

                  Working...
                  X