RAD Studio Builder 2007 - Access Violation



  • @Braunstein: Habe den Eintrag gefunden, funktioniert. Vielen Dank.

    Das Problem mit den ständig auftretenden Access Violations im Builder2007 konnte ich eingrenzen; verstehe es aber in keinster Weise. Ich habe ein neues Projekt eröffent, eine Form mit einem Menü angelegt (Form1).

    Hier der Code aus der Header-Datei (Main_Form1.h):

    //---------------------------------------------------------------------------
    
    #ifndef Main_Form1H
    #define Main_Form1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Menus.hpp>
    #include <ComCtrls.hpp>
    #include <ExtCtrls.hpp>
    #include <ImgList.hpp>
    #include <ToolWin.hpp>
    #include <Dialogs.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:																	// IDE-verwaltete Komponenten
    	TMainMenu *frm1_MainMenu;
    	TMenuItem *frm1_menuDatei;
    	TMenuItem *frm1_menuBearbeiten;
    	TMenuItem *frm1_menuDatei_Beenden;
    	TMenuItem *frm1_menuHilfe;
    	TMenuItem *frm1_menuHilfe_Information;
    	TPanel *frm1_panMandant;
    	TPanel *frm1_panGeraete;
    	TImageList *frm1_ImageList;
    	TToolBar *frm1_Symbole;
    	TToolButton *frm1_symNeu;
    	TToolButton *ToolButton2;
    	TToolButton *ToolButton3;
    	TStatusBar *frm1_StatusBar;
    	TPanel *frm1_panNetze;
    	TPanel *frm1_panSchrank;
    	TPanel *frm1_panKonfig;
    	TRichEdit *frm1_rtfPseudo;
    	TOpenDialog *frm1_dlgOpen;
    	void __fastcall frm1_menuDatei_BeendenClick(TObject *Sender);
    private:																		// Benutzer Deklarationen
    public:																			// Benutzer Deklarationen
     AnsiString PfadProg,PfadUpdate,PfadTemp,PfadKunde,PfadBackup,PfadBericht;		//
     AnsiString PfadClient,PfadGeraet,PfadGrafik,PfadHTML,PfadKonfig,PfadSchrank;	//
     AnsiString PfadVorlage,PfadMandant,PrgVersion,PrgLizenz,PrgBenutz;             //
     Boolean    oPrgComp;															//
     Integer    iFarbe;																//
    
    	__fastcall TForm1(TComponent* Owner);
    };
    
    //---------------------------------------------------------------------------
    
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    Hier der Quellcode direkt (Main_Form1.cpp):

    //---------------------------------------------------------------------------
    
    #include <dateutils.hpp>                                                        // Datumsfunktionen
    #include <inifiles.hpp>                                                         // INI Funktionen
    #include <systdate.h>                                                           // Datumsfunktionen
    #include <strutils.hpp>                                                         // Stringbearbeitung
    #include <vcl.h>                                                                // VCL
    
    #pragma hdrstop
    
    #include "FunktionenAllgemein.h"												// Grundfunktionen
    #include "Main_Form1.h"                                                         // Form1
    
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    //---------------------------------------------------------------------------
    
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {AnsiString z1,z2,zFile,zCode;		   	                                   // Vars definieren
     TIniFile *ini; 																// vorbereiten
    
     PrgLizenz  ="|FREEWARE|00000000|250|1|1|5|NetCat_Finder 2009|";                // aktuelle  Lizenz für Freeware
    
     PfadProg   =ExtractFilePath(Application->ExeName);                             // aktueller Ordner
     PfadKunde  =PfadProg +"Kunde\\";                                               //
    
     //--- CODE.INI LESEN ---//
     zFile=PfadKunde+"code.ini";                                                    // Pfad zur KUNDE.INI einstellen
     ini  =new TIniFile(zFile);                                                     // neue INI Instanz
     zCode=ini->ReadString("Kunde", "Lizenz", PrgLizenz);                           // auslesen
     delete ini;                                                                    // INI Handle löschen
     //ShowMessage(zCode+"\r\rFile: "+zFile);
    
     //if(zCode.SubString(1,1)!="|") { zCode=Codierer(1,7,zCode,""); }                // Daten sind codiert, also erst decodieren
     if(StrToIntDef(DatenPipe(1,2,zCode,"!!"),0)==0) {                              // Lizenz prüfen, wenn ungültig...
     // PrgLizenz  ="|FREEWARE|00000000|250|1|1|5|NetCat_Finder 2009|";               // aktuelle  Lizenz für Freeware einstellen
      z1=   "Diese Software ist eine Freeware-Version.\r\r";                        //
      z1=z1+"Einzelne Funktionen sind eingeschränkt.\r\r";                          //
      z1=z1+"Für weitere Informationen:  http://www.mtek-software.de";              //
      z2="Test";
      //z2=DatenPipe(1,6,PrgLizenz,"!!");                                             // Programmname an 6. Stelle ausschneiden
      Application->MessageBoxA(z1.c_str(),z2.c_str(),MB_OK | MB_ICONINFORMATION);   // Info geben
     }                                                                              // ende if(StrToIntDef
     else { PrgLizenz=zCode; }                                                      // unverschlüsselten Code direkt übergeben
    
    }
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    //---- MENU / MENÜS ----
    //---------------------------------------------------------------------------
    
    // MENU B
    void __fastcall TForm1::frm1_menuDatei_BeendenClick(TObject *Sender)
    {Form1->Close(); }
    

    Sobald ich eine der ausgesetzten Zeilen aktiviere, erhalte ich zu 80% die
    Violation-Fehler (manchmal geht es!? 😕 )
    Also einen von diesen hier:

    //if(zCode.SubString(1,1)!="|") { zCode=Codierer(1,7,zCode,""); }                // Daten sind codiert, also erst decodieren
     // PrgLizenz  ="|FREEWARE|00000000|250|1|1|5|NetCat_Finder 2009|";               // aktuelle  Lizenz für Freeware einstellen
      //z2=DatenPipe(1,6,PrgLizenz,"!!");                                             // Programmname
    

    Die Funktionen DatenPipe und Codierer sehen so aus:
    Header in FunktionenAllgemein.h:

    //---------------------------------------------------------------------------
    
    #ifndef FunktionenAllgemeinH
    #define FunktionenAllgemeinH
    //---------------------------------------------------------------------------
    #include <Printers.hpp>
    #include <Dialogs.hpp>
    //---------------------------------------------------------------------------
    
     AnsiString AuswahlOrdnerFile(int p1, int p2, AnsiString pt1, AnsiString pt2, AnsiString pt3);  //
     AnsiString Codierer(int p1, int p2, AnsiString pt1, AnsiString pt2);           //
     AnsiString DatenPipe(int p1, int p2, AnsiString pt1, AnsiString pt2);          //
     Boolean    DateiLoeschen(int p1, AnsiString pt1, AnsiString pt2);              //
     AnsiString Exportieren(int p1, int p2, int p3, AnsiString pt1, AnsiString pt2);//
     Boolean    HilfeFunktion(int p1, int p2, AnsiString pt1, AnsiString pt2);      //
     Boolean    Odd(int p1);                                                        //
     AnsiString PfadPruefen(int p1,int p2,AnsiString pt1,AnsiString pt2,AnsiString pt3);
     AnsiString ZeitStempel(int p1,AnsiString pt1);                                 //
    
    //---------------------------------------------------------------------------
    #endif
    

    Der Quellcode dann so (FunktionenAllgemein.cpp):

    //----------------------------------------------------------------------------
    //---- DATENPIPE ----
    //----------------------------------------------------------------------------
    AnsiString DatenPipe(int p1, int p2, AnsiString pt1, AnsiString pt2)
    {try {                                                                          // Fehlerroutine Start
     Integer i2; AnsiString z1,z2;                                                  // Vars definieren
    
     z1=pt1;                                                                        // Parameter übergeben
     if(pt1.Length()==0) { pt1="||"; }                                              // Stringvorgabe korrigieren
    
     switch(p1) {                                                                   // was machen?
     case 1:                                                                        // AUSLESEN STRING
     case 3:                                                                        // AUSLESEN INTEGER
      for(int i1=1;i1<=p2;i1++) {                                                   // x. Pipe suchen
       i2=z1.AnsiPos("|");                                                          // Pipe suchen
       if(i2==0) { z1=z1+"|"; i2=z1.AnsiPos("|"); }                                 // keines gefunden, neues Pipe anhängen
       z1=z1.SubString(i2+1,9999);                                                  // String ab Pipe+1 abschneiden
      }                                                                             // ende for(i1
    
      i2=z1.AnsiPos("|");                                                           // noch nächstes Pipe suchen
      z1=z1.SubString( 1,i2-1);                                                     // und bis nächstes Pipe den Inhalt ausschneiden
      if(pt2=="!!") { z1=z1.Trim(); }                                               // ohne Leerstellen zurückgeben
    
      if(p1==3 && z1.Length()==0) { z1="0"; }                                       // Rückgabe für Integer (leerer String gibt Fehlermeldung!)
      return z1;                                                                    // und Inhalt zurückgeben
     case 2:                                                                        // SCHREIBEN
      for(int i1=1;i1<=p2;i1++) {                                                   // x. Pipe suchen
       i2=z1.AnsiPos("|");                                                          // Pipe suchen
       z2=z2+z1.SubString(1,i2);                                                    // und Rest merken
       z1=z1.SubString(i2+1,9999);                                                  // String ab Pipe+1 abschneiden
      }                                                                             // ende for(i1
    
      i2=z1.AnsiPos("|");                                                           // noch nächstes Pipe suchen
      z1=z2+pt2+z1.SubString(i2,pt1.Length());                                      // und pt2 einsetzen und ab nächstem Pipe anhängen
      return z1;                                                                    // und Inhalt zurückgeben
     }                                                                              // ende switch(p1
    
     return "";                                                                     // Standardrückgabe
    
     } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "FunktionAllgemein.h: DateiPipe()", MB_OK); return "ERROR"; }  // Fehler anzeigen
    }
    

    Da es sporadisch funktioniert und im BCB6 immer, stehe ich vor einem absoluten
    Rätsel. Mir ist jetzt zumindest klar, warum der Builder2007 meine Projekte nicht
    fehlerfrei übernimmt. Gerade das obige und doch sehr einfach gestrickte Beispiel
    lässt mich aber verzweifeln. Was stimmt da nicht?

    Das letzte Patch vom Juni (ürbigens gegen Violation Fehler!) habe ich aufgespielt. Leider ohne Erfolg.

    Danke für jeden Hinweis.
    Gruss Stefan



  • Wenn du es mit dem Debugger verfolgst: wo genau scheitert es denn? Immer noch beim Startup?

    Hast du, falls die AV immer noch beim Start auftritt, dich mal mit dem Link beschäftigt, auf den ich dich in diesem Post verwies?



  • Hallo Audacia

    erstmal Danke für die Antwort. Mittlerweile habe ich sogar komplette
    Deinstallation und Neuinstallation vom RAD Builder 2007 vorgenommen
    (siehe meinen neuen Beitrag http://www.c-plusplus.net/forum/viewtopic-var-t-is-217175.html)
    und eine Projekt komplett neu aufgesetzt.

    Die Seite http://blogs.codegear.com/chrishesik/2007/05/24/34829
    habe ich gelesen; aber egal mit was ich starte, es kommt immer die Access
    Violation und für mich nichts aussagende Maschinensprachenanzeige. Woran
    erkenne ich den, was den AV ausgelöst hat? Weil Du danach gefragt hast:
    Von wem bekommst du eine AV? Von der IDE, dem Compiler, dem Linker, dem Programm selbst? ?

    Grüsse Stefan



  • Stefan7124 schrieb:

    habe ich gelesen; aber egal mit was ich starte, es kommt immer die Access
    Violation und für mich nichts aussagende Maschinensprachenanzeige.

    D.h., auch wenn du die Anwendung mit Shift+F7 startest, erhältst du sofort eine AV?

    Stefan7124 schrieb:

    Woran erkenne ich den, was den AV ausgelöst hat? Weil Du danach gefragt hast:
    Von wem bekommst du eine AV? Von der IDE, dem Compiler, dem Linker, dem Programm selbst? ?

    Wenn es sich um Compiler- oder Linker-AVs handelt, wirst du in den Build-Meldungen darüber informiert (außerdem kannst du das Programm dann gar nicht starten). Eine AV aus der IDE macht sich i.d.R. durch eine etwas konkretere Fehlermeldung bemerkbar, über deren "Details"-Button sich sogar ein Stacktrace anzeigen läßt. Über eine AV in der Anwendung benachrichtigt dich hingegen der Debugger mit einer Meldung wie dieser:

    ---------------------------
    Benachrichtigung über Debugger-Exception
    ---------------------------
    Im Projekt delphi_rtti.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 00401E82 in Modul 'delphi_rtti.exe'. Schreiben von Adresse 00000000' aufgetreten.
    ---------------------------
    Anhalten Fortsetzen Hilfe
    ---------------------------

    Freundlicherweise informiert der Debugger dich auch gleich, an welcher Adresse die AV auftritt (du erreichst die Stelle, indem du die CPU-Ansicht öffnest, dort im Kontextmenu "Zu Adresse gehen..." wählst und die fragliche Adresse, in meinem Beispiel also :00401E82, eingibst), und da er die Ausführung an der Stelle unterbricht, hast du auch gleich den Call-Stack zur Verfügung. Auch wenn du mit dem Disassembler noch nichts anfangen kannst, so kannst du doch herausfinden, wo etwa im Code du dich befindest, denn wenn du im Debug-Mode kompiliert hast, ist im Assembler-Code immer wieder eine eingeschobene, fettgedruckte Delphi- oder C++-Quelltextzeile mit Datei- und Zeilenangabe zu finden.

    Auch wenn du dich nicht in der Lage siehst, die Fehlerursache so weiter zu lokalisieren, wäre es sicher hilfreich, wenn du zugunsten besserer Fernanalysemöglichkeiten die exakte Fehlermeldung, den Call-Stack und die entsprechende Stelle des Assembler-Codes, am besten mit einigen Zeilen Vorlauf, hier posten würdest.



  • Hallo Audacia

    Danke für Deine Tipps; mit Shift+F7 kommt auch ein Access-Violation.

    Der Quellcode:

    /---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Main_Form1.h"															// Form1 Main
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
    }
    
    //---------------------------------------------------------------------------
    // --- MENU / MENÜ ---
    //---------------------------------------------------------------------------
    
    // MENÜ B
    void __fastcall TForm1::frm1_menuDatei_BeendenClick(TObject *Sender)
    {Form1->Close();
    }
    

    Primitiver geht es glaube ich kaum noch 😉

    Hier der Screenshot von der Fehlermeldung:
    http://www.mtek-software.de/Aceess_Violation_Shift+F7__1.jpg

    Und hier die CPU Anzeige:
    http://www.mtek-software.de/Aceess_Violation_Shift+F7__2.jpg

    Und hier habe mal den Quellcode als ganzes mit allen Dateien abgelegt:
    http://www.mtek-software.de/netcat_finder_2009.zip

    Gerade habe ich mit Erstaunen festgestellt, daß er bei einem Start mit
    F5 (oder Shift+F7) eine Netcat_Finder_2009.tds Datei erzeugt mit fast
    6 MB Größe (!!!) 😕 Was ist das denn bitte? Wenn ich diese
    nämlich lösche, kann ich einmal OHNE Access-Violation Fehler starten, danach
    ist diese große Datei wieder da und ich bekomme mit dem nächsten Start wieder
    die Access-Violation Meldungen.

    Danke im vorraus für jeden Hinweis.

    Der Support von Borland hat übrigens bis heute nur den Eingang meiner Störungsmeldung bestätigt, ansonsten geschwiegen.

    Gruss Stefan



  • Hallo,

    Die tds (Turbo Debugger Symbols) enthält die Debugger-Symbole.



  • Ich habe jetzt gerade auch mal dein Projekt bei mir getestet und es läuft problemlos. Es scheint also ein Problem deiner Installation bzw. deines Systems zu sein. Evtl. sind da irgendwo alte dlls oder so mit im Spiel.



  • Hallo Braunstein

    habe jetzt auf meinem Laptop (mit XP und BCB6 und genau wie mein Festrechner ebenfalls ein sehr sauberes System, d.h. alls ServicePacks drauf, nur OpenOffice, Thunderbird und Firefox und BCB drauf) den C++ Builder 2007 neu installiert und zu meinem Entsetzen mit einem neuen Projekt und einem TButton das Problem, daß das Projekt zwar fehlerfrei startet (danke an Borland dafür), beim Schliessen diesen Mammutprojektes dann allerdings auch einen Access Violation Fehler kommt (nehme den Dank zurück und bin stinkesauer, für alle zur Erinnerung: Die Software kostet ein paar Hundert Euro! Keine Reaktion seit 1 Woche vom Support, keine Anlaufstelle telefonisch bei Borland sprich CodeGear zu finden usw. Jeder der in Zukunft auf neuere Versionen von CodeGear umsteigen will, sollte das mal mit berücksichtigen!) Es kann ja kaum angehen, daß selbst ein simples Formelement mit einer Komponente auf zwei unterschiedlichen Rechnern und zwei unterschiedlichen WinVersionen auf Anhieb nach Neuinstallationen nicht läuft! 😡

    Wedre daher meinen BCB Builder 2007 verkaufen und beim BCB6 bleiben, der läuft wenigstens. Falls ihn also einer haben möchte (mit Rechnung, dann kurze Mitteilung an mich).

    Übrigens ist der Access Violation Fehler bei CodeGear nicht unbekannt; es gibt deshalb ein Patch im Juni 2008, der allerdings KEINE Abhilfe bringt. Und jeder, der das liest und schreiben möchte, daß es ein mächtiges Tool ist usw. sollte sich vorher noch überlegen, ob er in anderen Bereichen solchen Müll für solche Summen so aktzeptieren würde. 👎

    Gruss Stefan



  • Hallo zusammmen,

    nach einer Tasse Kaffee und der Überlegung, was an beiden Rechnern identisch sein könnte, kam ich auf meine WebCam Logitech. Diese auf beiden Rechnern komplett entfernt (3 Softwarepakete) und viola, auf beiden Fehlern ist der Access Violatio Fehler weg. Im Internet danach gesucht und siehe da:
    http://bdntv.borland.com/pix/nickhodges/Camtasia/Logitech/Logitech.html

    Der Fehler ist bei CodeGear bekannt (25. Januar 2008) und gut versteckt.

    Wer also den gleichen Fehler hat, Kamera deinstallieren und alles läuft.

    Über das Thema saubere Programme bzw. das Mischen von DLL Dateien usw. im Systemverzeichnis von Windows lasse ich mich jetzt mal nicht weiter aus (kann sich jeder seinen Teil denken).

    Danke an alle für ihre Tipps und Bemühungen und hoffe mal, dieser Artikel
    hilft auch mal einem anderen weiter. 😉

    Stefan


Anmelden zum Antworten