![]() |
Exception ''access violation ' beim beenden des Programms
Hallo Zusammen,
grundsätzlich die Frage, gibt es ein Tool welches auch Exceptions direkt beim beenden der Anwendung erkennt um die Ursache zu finden?
Code:
Im Projekt XY.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'access violation at 0x09e6cad2: read of address 0x0622cc48' aufgetreten.
Ich verwende in ein Projekt ein Hardware (SignPad) um eine Unterschrift zu digitalisieren. Die Hardware liefert ein ActiveX Control um die Unterschrift anzuzeigen. Auf einer VCL-Form wird das ActiveX-Control abgelegt zum anzeigen der Unterschrift beim Digitalisieren. Rufe ich die Form aus einer neuen normale VCL-Form Anwendung auf, unterschriebe und beende die Anwendung wird keine Exception ausgelöst. Erzeuge ich nun eine neue MDI-Form Anwendung und rufe die gleiche Form auf, unterschriebe und beende die Anwendung, kommt die Exception. EurekaLog (aktuelle Testversion) merkt die Exception nicht! Ich habe es jetzt vorübergehend so gelöst dass ich die VCL-Form Anwendung mit der Unterschrift-Form eine eigene Exe erzeuge und die Exe aus der MDI-Anwendung aufrufe. Das funktioniert scheinbar immer. Langzeittests habe ich noch nicht durchgeführt. Kennt jemand so ein Tool? Ich habe AQTime noch nicht verwendet. Kann es möglicherweise so etwas aufspüren? Gruß Kostas |
AW: Exception ''access violation ' beim beenden des Programms
Ja, das Tool heißt Debugger und Stacktrace
|
AW: Exception ''access violation ' beim beenden des Programms
Hallo Sir Rufo,
bei jeder exception bekomme ich eine neune Adresse. Ich kann also nicht nach dem Compilieren auf eine Adresse springen. Hast du mir bitte ein Hinweis wie ich vorgehen muss? Gruß Kostas |
AW: Exception ''access violation ' beim beenden des Programms
Starte dass Programm mit dem Debugger und wenn die Exception geworfen wird, dann poppt erst ein Fenster von der IDE auf, da dann auf abbrechen und man befindet sich im Quelltext- oder CPU-Fenster.
Links oben befindet sich idR der Stacktrace, den man dann mal Schritt für Schritt zuruckgeht, bis man an die Stelle im eigenen Code kommt. Dort befindet sich dann die Stelle, die für das Auslösen mittelbar verantwortlich ist. Meine Vermutung Der Fehler tritt bei einer MDI Anwendung auf. Kann es sein, dass du das Fenster extra erzeugst, aber zusätzlich auch schon im Hintergrund eine Form-Instanz erstellt wurde (in der .dpr nachschauen). Diese automatisch erzeugte Instanz wird beim Beenden natürlich entsorgt, aber dabei wird auf etwas zugegriffen, was du mit der manuell erzeugten Form-Instanz schon abgeräumt hast. ;) Das ist natürlich nur ein Blick durch die Glaskugel, dein geposteter Quellcode war mir einfach zu lang |
AW: Exception ''access violation ' beim beenden des Programms
Obwohl das von Sir Rufo beschriebene Verfahren vermutlich zum Ziel führt, versagt klassisches Debuggen häufig, vorzugsweise beim Beenden eines Programms. Wenn der Fehler nicht im eigenen Code liegt, dann wird es schwierig. Wir treffen hier auf Seiteneffekte, d.h. Probleme, die deshalb auftreten, obwohl man eigentlich nichts Falsches gemacht hat. Wer hätte z.B. gedacht, das man Probleme beim Beenden bekommt, wenn man Threads mit 'FreeOnTerminate=True' startet?
Andere Fallstricke sind die `Finaliziation` Abschnitte eigener oder fremder Units. Oder irgendein Destruktor, der falsch aufräumt. |
AW: Exception ''access violation ' beim beenden des Programms
Zitat:
![]() |
AW: Exception ''access violation ' beim beenden des Programms
Zitat:
also das ActiveX Control wird erzeugt, kann ich beenden und erneut aufrufen ohne Probleme. Wenn ich jedoch nach dem öffnen des Forms auf die Idee komme, das SignPad zu aktivieren zum unterschrieben, und danach die App beenden bei einer MDI-App dann knallts. Das ActiveX Control macht über die importierte TLB irgend welche DLL aufrufe und die Hardware zu steuern. Doch warum nur beim beenden einer MDI-App der Fehler auftritt und nicht bei einer VCL-Forms App ist mir sehr schleierhaft. Im Stacktrace zu suchen ist nicht so einfach denn ich habe keinen Hinweis was es für ein Fehler ist. Gruß Kostas P.S. ich werde auch mal das Tool madExcept ausprobieren. |
AW: Exception ''access violation ' beim beenden des Programms
Es gibt ein paar Unterschiede zwischen MDI- und Nicht-MDI-Forms. So wird bei einem MDI-Child beim Close kein Hide sondern nur ein Minimize ausgeführt. Je nachdem was deine Eventhandler so tun wird das im einen Fall ausgeführt und im anderen nicht.
|
AW: Exception ''access violation ' beim beenden des Programms
Hallo Uwe,
das ist es leider auch nicht. Die Form ist eine Modale Form. Dessen Unit hat eine Methode um die Form zu erzeugen und zeigt sie per ShowModal an.
Delphi-Quellcode:
Die Form beinhaltet also nur das ActiveX Control und zwei drei Buttons. Wenn die Form erzeugt wird und somit auch das ActiveX Control,
function StartfrUnterschrift:TModalResult;
begin with frUnterschrift do begin frUnterschrift := TfrUnterschrift.create(Application); try result := ShowModal; finally release; frUnterschrift:=nil; end; end; end; und die App wird beendet, passiert nichts. Wenn jedoch die Form erzeugt wird und man die Methode vom ActiveX Control ausführt, kommt die exception jedoch nur bei MDI-Apps. Mittlerweile habe ich auch madExcept ausprobiert, auch dieses Tool merkt die exception nicht. Die Exception wird vermutlich in der DLL vom SignPad ausgelöst. Vermutlich wird irgend ein Handle nicht mehr existieren. Ich werde mal den Hersteller fragen. Ich gehe nicht davon aus der es den Fall kennt, aber fragen kann man ja mal. Gruß Kostas |
AW: Exception ''access violation ' beim beenden des Programms
Delphi-Quellcode:
with frUnterschrift do
begin frUnterschrift := TfrUnterschrift.create(Application); try result := ShowModal; finally release; frUnterschrift:=nil; end; end; Das tut aber jetzt schon weh! Ich habe jetzt auch keine Lust auszuprobieren, was da wirklich passiert, aber lös doch bitte mal das with auf... |
AW: Exception ''access violation ' beim beenden des Programms
Delphi löst ein WITH gerne so auf:
Delphi-Quellcode:
Und jetzt mag gern jemand raten, was da nun passiert.
function StartfrUnterschrift:TModalResult;
var AutomatischGenerierteVariable: TfrUnterschrift; begin //with frUnterschrift do AutomatischGenerierteVariable := frUnterschrift; begin frUnterschrift := TfrUnterschrift.create(Application); try result := AutomatischGenerierteVariable.ShowModal; finally AutomatischGenerierteVariable.release; frUnterschrift:=nil; end; end; end; Und wozu gibt es da überhaupt eine globale Variable "frUnterschrift", wo die ja scheinbar nicht außerhalb benutzt wird, oder etwa doch?
Delphi-Quellcode:
Beim Release wird das Free nicht sofort ausgeführt, sondern verzögert "irgendwann" später mal,
function StartfrUnterschrift: TModalResult;
begin with TfrUnterschrift.Create(Application) do begin try Result := ShowModal; finally Free; end; end; end; was auch gerne Probleme erzeugt und vorallem beim Focus ist uns das schon schmerzhaft auf die Füße gefallen. Und das "Start" im Namen stimmt auch nicht wirklich, denn das Fenster wird erzeugt (gestartet), verarbeitet (ShowModal) und wieder beendet (Release/Free). |
AW: Exception ''access violation ' beim beenden des Programms
Die Variable "frUnterschrift" ist die Formvariable die die Form repräsentiert, wird von Delphi erstellt.
Ihr habt recht. Das With ist völlig überflüssig gewesen. Ich verwende dennoch das With wie angezeigt da ich meist vor dem ShowModal irgend welche Initialisierungen mache und nach dem ShowModal übergebe ich die Rückgabewerte. Das With verwende ich damit ich die Formvariable nicht jedes mal angeben muss. Bis Dato hatte ich damit auch nie Probleme. Diesem Methodenrumpf habe ich mir als Vorlage abgelegt und verwende sie tausendfach. In diesem Fall wo nichts initialisiert wird und nicht zurückgegeben wird ist es völlig unnötig. Das Create im With mache ich bewusst nicht mehr. Damit hatte ich schon massive Probleme. Wenn ich z.B. über einen qualifizierten Bezeichern arbeiten muss habe ich keinen Zugriff auf die Formvariable da die Form im With erzeugt wird. Es gab noch mehr Probleme, ich kann mich aktuell nicht an einen Fall erinnern.
Delphi-Quellcode:
Gruß Kostas
function StartfrUnterschrift: TModalResult;
begin with TfrUnterschrift.Create(Application) do begin try Result := ShowModal; finally Free; end; end; end; |
AW: Exception ''access violation ' beim beenden des Programms
Zitat:
Vorallem bei manuell erstellten Formularen sollte man am Besten die Finger davon lassen und diese Variable einfach löschen.
Delphi-Quellcode:
Das dachte Viele und dann knallte es plötzlich.
Bis Dato hatte ich damit auch nie Probleme.
PS: Records können Methoden und Property enhalten. Jetzt hat "endlich" TPoint und TRect ganz nette Funktionen direkt eingebaut und nicht mehr wild sonstwo als Funktionen rumliegen.
Delphi-Quellcode:
Könnte z.B. das Height der Form sein, oder z.B. von einem TBitmap, welchers drumrum ebenfalls via WITH rumgammelt.
var
R: TRect; with R do begin ... {eigentlich nicht R.}Height := {R.}Bottom - {R.}Top; {eigentlich nicht R.}Offset := {R.}Top; end; Oder eine Variable "Offset". Tja, und nun hat man seinen Spaß. Das OFFSET knallt, weil mit TRect.Offset nun eine Funktion existiert. Und es gibt jetzt ein solches HEIGHT-Property, somit wird es nun zu R.Height:= und ist nicht mehr das andere Height. |
AW: Exception ''access violation ' beim beenden des Programms
Ja, in C# ist das alles deutlich besser gelöst.
Eigentlich wird es Zeit dass Delphi in Ihrer Sprache wächst. [Edit] C# hat leider mittlerweile solche Dimensionen erreicht dass es hoffnungslos überfrachtet ist meiner Meinung nach. [Edit] Ich habe soeben in der Main Form eingefügt:
Delphi-Quellcode:
Die Exception wird erst nach dem MessageDlg gefeuert. Somit ist klar warum madExcept und EurekaLog nicht haben reagieren können.
initialization
finalization MessageDlg('Test', mtWarning, [mbOK], 0); Die Exception wird somit außerhalb vom Programm gefeuert. Jetzt bleibt nur der Weg zum Hersteller des SignPads. Gruß Kostas |
AW: Exception ''access violation ' beim beenden des Programms
Zitat:
Zitat:
|
AW: Exception ''access violation ' beim beenden des Programms
Hallo Zusammen,
ich hatte heute Zeit und hab die Ursache lokalisieren können. Für die Anwendung verwende ich ein SignPad und eine Unterschrift zu digitalisieren. Auch wird die Komponente TJvMultiStringHolder verwendet, hat aber nicht mit dem SignPad zu tun. Wenn im Projekt die Komponente TJvMultiStringHolder vorkommt und das SignPad eine Unterschrift digitalisiert und die Anwendung wird beendet, dann kommt die Exception. Entferne ich die Komponente, so funktioniert alles einwandfrei. Oder ich digitalisiere nicht. Das habe ich in einem neuen Testprojekt feststellen können. Übrigens, das ist das zweite SignPad. Zuerst hatte ich eines von Wacom und genau den gleiche Fehler gehabt. Da war ich der Meinung, natürlich liegt es an Wacom. Die haben den Treiber ober API nicht sauber programmiert. Dann habe ich Wacom entsorgt und bei StepOver eingekauft. Die Überraschung war groß als ich die Exception schon wieder bekommen habe. Gruß Kostas. P.S. Kennt jemand eine alternative Komponente zu TJvMultiStringHolder? Es geht darum das in der Exe mehrere String gebunkert werden können. Ich benutze das als Updatescripts um eine FB-DB in Abhängigkeit von der Exe-Version die DB-Struktur hoch zu ziehen. [Edit] ich habe eine Ersatzkomponente gefunden für TJvMultiStringHolder ![]() Damit gibt es keine Probleme. |
AW: Exception ''access violation ' beim beenden des Programms
Ja, die Alternative heißt resourcestring bzw. rc-file und brcc.
|
AW: Exception ''access violation ' beim beenden des Programms
Zitat:
Wenn es wirklich eine TStringList ist (kein anderer TStringsNachfahre), dann kann man dort in jede Zeile jedes
Delphi-Quellcode:
bzw.
SL[i]
Delphi-Quellcode:
mehrere "Zeilen" reinmachen. (man darf nur niemals über SL.Text, SL.SaveFile usw. gehen, da dort die Zeilenumbrüche aufgelöst werden)
SL.Strings[i]
Via ![]() Oder
Delphi-Quellcode:
bzw.
TDictionary<string,string>
Delphi-Quellcode:
.
TObjectDictionary<string,TStringList>
Diese Komponenten muß man zwar selber verwalten, aber was soll's. PS: Deine "Ersatzkomponente" ist sowas ähnliches wie das TObjectDictionary, also mehrere TStringListen in einer Komponente, nur daß diese Dictionaries wie eine Hash-Liste arbeiten und somit einen schnelleren Zugriff bieten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 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