Hallo!
Ich habe ein nicht reproduzierbares Problem in einer meiner Anwendungen. Das Programm stützt beim Programmende ab. Es kommt während der Ausführung der Finalisierungsprozeduren der Units irgendwann zu einem Fehler. Die Liste der anzuspringenden Finalisierungsroutinen wird zerschossen. Diese Liste enthält ca. 70 Adressen, die beim Programmende vom System angesprungen werden: Das hat nichts mit meinem Code zu tun (teht irgendwo im Delphi-Code). Je nachdem, in welcher Reihenfolge ich die Units in den 'Uses' Anweisungen sortiere, tritt der Fehler mal an Position 35 oder 40 oder so auf. Irgendeine Adresse wird zerballert, da die
Exception nicht *in* der Finalisierungsroutine auftritt, sondern beim *Aufruf* Derselben. Ergo wird diese Liste zerballert. Das Programm gerät zu allem Überfluss in eine Endlosschleife, d.h. nach Klick auf 'OK' im
Exception-Dialog, wird der gleich nochmal angezeigt. Oder noch besser: Der Bildschirm wird mit
Exception-Dialogen zugekleistert: Nach einigen Hundert Stück ist dann Ruhe...
Ich suche nun schon seit Ewigkeiten nach einem Fehler und habe nun eine Theorie:
Das Programm arbeitet exzessiv mit
COM-Objekten.
Ich habe also ein Hauptformular mit einem Grid, in dem sind die Objekte angezeigt. Beim Klick auf den Edit-Button wird ein Bearbeitungsdialog geöffnet. Mit OK/Cancel wird der wieder verlassen. Nichts ungewöhnliches. Aber jetzt:
Ich habe für jedes
COM-Objekt einen Wrapper, sowas wie :
Delphi-Quellcode:
Type
TWrappedObject = Class
Private
fIntf : IMyObject;
Public
Constructor Create (aIntf : IMyobject);
Destructor Destroy;
...
End;
Das Editieren erzeugt ca. 100-300 Wrapper-Objekte, die beim Verlassen des Formulars wieder freigegeben werden. Da das Freigeben einige Zeit dauert habe ich mir einen Thread geschrieben, der das im Hintergrund macht (häppchenweise zu 16 Stück). Ich habe schon über eigene Referenzzähler geprüft, ob alle Objekte freigegeben werden und die
COM-Teile auch. Alles scheint 100% in Ordnung zu sein.
Neulich ist mir etwas sauer aufgestossen: Man kann doch an einen Thread einfach die Interfacezeiger übergeben. Da war doch was? Muss ich die nicht über den Marshaller irgendwie konvertieren?
Wer kennt sich damit aus?
Ach ja: Beispielcode bringt nichts, weil ich den Fehler nicht eingrenzen oder lokalisieren kann und er auch noch sporadisch auftritt. Immer wenn ich ihn zeigen will, funzt es, aber beim Kunden knallt es weg: Er kennt sich mittlerweile sehr gut mit dem Taskmanager aus..