Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport (https://www.delphipraxis.net/175493-xe4-probleme-beim-beenden-der-anwendung-donemonitorsupport.html)

Alex_ITA01 25. Jun 2013 20:32


XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Hallo zusammen,
ich habe seit heute XE4 Pro und habe meine Anwendung von Delphi 2009 übernommen. Ein paar Anpassungen musste ich machen aber es lässt sich alles compilieren und ich habe auch keine Warnungen oder Fehler.

Unter Delphi 2009 konnte ich meine Anwendung ganz normal beenden (Threads freigeben, Objekte freigeben, Formulare freigeben usw.).
Unter XE4 habe ich das Problem, dass die Anwendung zwar runter fährt aber in der Delphi IDE wird mir oben in der Titelleiste immernoch angezeigt "wird ausgeführt" und wenn ich in die CPU Ansicht gehe und ich weiter debugge, sieht es nach einer Endlosschleife oder sowas aus, da er immer über die gleichen Aufrufe an die gleiche Stelle kommt.

Ich habe bereits meine Anwendung debuggt und mein Hauptfenster kommt ins FormDestroy und auch der letzte Thread wird freigegeben.
Habt ihr eine Idee, wie ich rausfinden kann, wer da am Ende hängen bleibt, sodass Delphi immernoch sagt "wird ausgeführt"? Unter Delphi 2009 ging das übrigens.

Nutze Win8, 64bit -> Anwendung als 32bit compiliert.

Gruß
Alex

jaenicke 25. Jun 2013 21:17

AW: XE4 Probleme beim Beenden der Anwendung
 
Du kannst z.B. die finalization Abschnitte durchdebuggen indem du einen Haltepunkt auf das end. in deiner Projektdatei setzt. Dafür musst du ggf. Debug-DCUs aktivieren. Du wirst dann in Aufrufe aus FinalizeUnits gelangen, mit denen die einzelnen Units finalisiert werden. Irgendwo da bleibt das Programm dann hängen.

Beliebt ist bei Verwendung von Threads z.B. ein WaitFor beim Beenden nachdem die Anwendung schon herunterfährt. Dann wird nämlich kein CheckSynchronize aus OnIdle mehr aufgerufen und Synchronize-Aufrufe schlagen fehl. Da man gleichzeitig auf den Thread wartet, ist das ein typischer Deadlock. Das ist nur ein Beispiel, genauer musst du das selbst debuggen...

Alex_ITA01 26. Jun 2013 09:13

AW: XE4 Probleme beim Beenden der Anwendung
 
Habe ich probiert mit dem Debuggen nach dem .End
Da lande ich in der System.pas in der procedure _Halt0;

Da ist eine While True do Schleife drinne, die ich aber nicht genau verstehe.
In irgendwelche finalization Abschnitte komme ich leider gar nicht.
Es sind auch Fremdkomponenten (TMS) im Einsatz und ich weiß gar nicht, welche Unit denn überhaupt alles finalization Abschnitte nutzt...

Hast du noch eine Idee, was ich machen könnte bzw. wie ich über das CPU Fenster herausfinden kann, welcher Thread vielleicht hängt?

Ein WaitFor ist bei uns nicht im Einsatz.

Gruß

baumina 26. Jun 2013 09:28

AW: XE4 Probleme beim Beenden der Anwendung
 
Zum Eingrenzen solch seltsamer Fehler kommentiere ich immer möglichst viele Dinge einfach aus. In deinem Fall würde ich versuchen die Threads mal komplett rauszunehmen.

Alex_ITA01 26. Jun 2013 10:20

AW: XE4 Probleme beim Beenden der Anwendung -> DoneMonitorSupport
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hab gefunden in welchen finalization Abschnitt er hängt.
System.SysUtils -> DoneMonitorSupport -> CleanEventList -> repeat until AtomicCmpExchange(EventCache[I].Lock, 1, 0) = 0;

Dort bleibt er ewig hängen.
Uwe Raabe hatte dazu hier schonmal was geschrieben:
http://stackoverflow.com/questions/1...upport-on-exit

Ich vermute TMS benutzt das Objekt TMonitor, da ich es definitiv nicht nutze.

Gibt es da eine Info, was man genau machen kann / sollte?

Werde TMS mal kontaktieren.

Die System.SysUtils.pas kann man ja leider nicht ändern und neu compilieren oder gibts da doch ein Weg dafür?

// Neu:
Ich habe das ganze jetzt mal mit 64bit probiert und siehe da, es geht.

Habe zwei Screenshots angefügt, wo man sieht, wie das Array "SyncEventCache" aussieht zwischen 32 und 64 bit.

Da sieht man auch, das es dann eben bei 64bit geht, weil da keine "1" in einem der Events steht.
Hoffe hier kann jemand helfen?!

Gruß
Alex

Alex_ITA01 9. Sep 2013 20:44

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Hallo zusammen,
ich muss das Thema nochmal auffrischen, weil es für mich hier immernoch keine Lösung gibt.
Einen entsprechenden QC habe ich gemacht aber ich kann und darf meine Anwendung leider nicht dort posten (diese würde wahrscheinlich auch den Rahmen des Supportes sprengen -> >700000 Zeilen, TMS gekauft und voll im Einsatz usw.).

Gibt es denn irgendeine Möglichkeit, entweder die vorhandene Funktion "DoneMonitorSupport" in der System.SysUtils.pas zu ändern oder das man diesen MonitorSupport abschaltet? Meine Anwendung funktionierte unter D2009 ja auch. Wenn ich wenigstens ein Hinweis darauf bekommen würde, welches Event dort nicht freigegeben ist, dann könnte ich ja auch danach suchen aber so...

Hoffe hier kann mir noch jemand weiter helfen.

Danke und Gruß
Alex

Uwe Raabe 9. Sep 2013 23:28

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
TMS Components verwendet meines Wissens kein TMonitor. Allerdings wird es in XE4 an deutlich mehr Stellen in der VCL verwendet als noch in D2009 (sogar in BDE.DBTables). Es kann also durchaus sein, daß es sich um ein ganz normales RTL/VCL-Objekt handelt, daß in XE4 jetzt den Monitor-Support nutzt. Wenn du eine dieser Instanzen nicht freigibst, dann kann genau dieses Verhalten auftreten.

Du kannst ja mal probeweise den MonitorSupport überwachen, in dem du folgende Unit einbindest:

Delphi-Quellcode:
unit WrapMonitorSupport;

interface

implementation

var
  SaveMonitorSupport: PMonitorSupport;

function NewSyncObj: Pointer;
begin
  result := SaveMonitorSupport.NewSyncObject;
end;

procedure FreeSyncObj(SyncObject: Pointer);
begin
  SaveMonitorSupport.FreeSyncObject(SyncObject);
end;

function NewWaitObj: Pointer;
begin
  result := SaveMonitorSupport.NewWaitObject;
end;

procedure FreeWaitObj(WaitObject: Pointer);
begin
  SaveMonitorSupport.FreeWaitObject(WaitObject);
end;

function WaitOrSignalObj(SignalObject, WaitObject: Pointer; Timeout: Cardinal): Cardinal;
begin
  result := SaveMonitorSupport.WaitOrSignalObject(SignalObject, WaitObject, Timeout);
end;

const
  MonitorSupport: TMonitorSupport = (
    NewSyncObject: NewSyncObj;
    FreeSyncObject: FreeSyncObj;
    NewWaitObject: NewWaitObj;
    FreeWaitObject: FreeWaitObj;
    WaitOrSignalObject: WaitOrSignalObj;
  );

initialization
  SaveMonitorSupport := System.MonitorSupport;
  System.MonitorSupport := @MonitorSupport;
end.


Einfach BreakPoints in die Wrapper setzen und schauen, wer die aufruft.

Alex_ITA01 10. Sep 2013 07:47

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Hallo Uwe,
ich habe mich selber schonmal in die Funktion "TMonitor.Enter" debuggt und geguckt, wer das alles aufruft.
Ich bin dann schließlich auf TThread gestoßen, der beim Create ein Objekt "ThreadLock" erstellt, welches dann mit TMonitor.Enter und TMonitor.Exit genutzt wird. Und im Destructor wird dieses Objekt dann wieder freigegeben.

Das komische ist ja, dass es nicht immer auftritt dieser Fehler.
Mal funktioniert es, mal bleibt er hängen in der Schleife.

Bei einem Kollegen, der den gleichen Quelltext compiliert (auf einem anderen PC), funktioniert es komischerweise nie. Irgendwie kommt mir das sehr komisch vor. Wenn ich eine Exe habe, mit der es gerade mal funktioniert, dann funktioniert es auch immer mit dieser Exe. Wenn mein Kollege diese funktionierende Exe nimmt und bei sich auf dem PC testet, funktioniert es bei ihm auch. Das hört sich doch für mich nach irgendeinen Compilerfehler an, der in die Exe rein compiliert wird oder nicht?

Gruß
Alex

Uwe Raabe 10. Sep 2013 08:12

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1227801)
Das hört sich doch für mich nach irgendeinen Compilerfehler an, der in die Exe rein compiliert wird oder nicht?

Hört sich eher nach ungültigen dcu-Dateien an. Machst du immer ein Build oder nur ein Compile? Es kann manchmal vorkommen, daß solche dcus entstehen, wenn man z.B. eine pas-Datei aus der Versionskontrolle zurücksetzt. Die vorher erstellte dcu ist dann neuer als die pas und schon passt was nicht zusammen. Es gibt aber noch dutzende andere mögliche Gründe für solche Effekte. Eine beliebte Quelle sind auch unterschiedliche Compiler-Einstellungen.

Alex_ITA01 10. Sep 2013 08:24

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Hallo Uwe,
was ich auch nicht verstehe ist, dass es bei einem 64 Build nie schief geht bei mir.
Wir machen eigentlich immer Umsch+F9 zum Projekt erzeugen und löschen per Batch Datei vorher alle alten DCUs.

Komisch ist irgendwie auch, dass immer in dem Haltepunkt "CleanEventList(SyncEventCache);" das SynchEventCache immer genau 3 Einträge drinne hat (nie mehr oder weniger) und manchmal ist das "Lock" von einem dieser Einträge auf 1 und damit hängt das ganze...

Irgendwie komisch. Aber ich bin ja nicht der einzige mit dem Problem so wie ich im Netz gelesen habe.
Kann man hier nicht irgendwie direkt an Embacadero ran treten und ein HotFix/Patch erfragen, damit es nicht hängen bleibt sondern einfach nur die Lock Eigenschaft abfragt auf 0 und nur dann freigibt...

Gruß
Alex

Edit:
Was mir jetzt noch grad dazu einfällt:
Ich ändere nichts am Quelltext und lösche per BatchDatei immer alle DCUs. Dann mache ich immer ein Rebuild mit Umschalt+F9 und die anschließend erzeugte Exe (32bit) funktioniert mal und mal nicht. Das kann doch gar nicht sein oder? Wenn die Exe dann mal funktioniert, dann funktioniert sie auch auf dem PC von meinem Kollegen. Das kann doch dann auch keine Einstellung am Compiler sein, diese ändere ich ja schließlich nicht

Alex_ITA01 10. Sep 2013 12:13

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt mal D2009 mit XE4 verglichen.
Das DoneMonitorSupport gibt es nämlich unter D2009 auch schon nur werden standardmäßig keine Events eingetragen (TMonitor.Enter -> TMonitor.GetEvent -> MonitorSupport.NewSyncObject).

Anbei mal ein Screenshot wo man den Unterschied im TThread deutlich sieht.
Das hat sich nämlich geändert zwischen den beiden Delphi Versionen.

(System.)Classes.pas

XE4: class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);

Dort wird mit TMonitor.Enter/Exit gearbeitet

D2009: class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);

Hier wird mit EnterCriticalSection(ThreadLock) und LeaveCriticalSection(ThreadLock) gearbeitet.

Schön wäre es jetzt natürlich, dass gleiche Verhalten wie unter D2009 wieder zu erzeugen.

Gruß
Alex

Uwe Raabe 10. Sep 2013 12:30

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1227824)
Schön wäre es jetzt natürlich, dass gleiche Verhalten wie unter D2009 wieder zu erzeugen.

Ich würde eher versuchen, die Instanzen zu finden, die unter bestimmten Bedingungen offenbar nicht freigegeben werden. Dann hast du das Problem beim nächsten Update nämlich auch nicht mehr. Grundsätzlich funktioniert DoneMonitorSupport ja, wenn wirklich alle Objekte, die TMonitor verwenden auch wieder freigegeben werden. Auch wenn du das jetzt irgendwie hin flickst, so daß der Hänger nicht auftritt, bleibt doch ein unangenehmer Beigeschmack - würde es zumindest bei mir.

Alex_ITA01 10. Sep 2013 13:24

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Klar, ich will es eigentlich auch richtig gelöst haben und nicht irgendwie gefuscht.
Das Problem ist ja, dass ich nicht genau weiß, wer alles TMonitor verwendet (scheinen ja in der neuen Delphi Version jede Menge Controls/Objecte zu sein) und wie ich vielleicht anhand der EventAdresse auf das Object schlussfolgern könnte.

Gruß
Alex

baumina 10. Sep 2013 13:44

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Als ich mit Threads angefangen habe, hatte ich die dollsten sporadischen Zugriffsverletzungen und sonstigen Mist. Deswegen tippe ich weiterhin darauf, dass dieses Verhalten von einem Thread ausgelöst wird. Gibt es für dich nicht die Möglichkeit diese Threads mal alle auszukommentieren, um zu schauen ob das Problem bleibt?

jaenicke 10. Sep 2013 13:59

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Ich habe das sehr einfach gelöst...
FastMM4 im FullDebugMode, Haltepunkt auf die genannte Schleife, per Assemblerfenster manuell aus der Schleife in DoneMonitorSupport raus und dann alle Speicherlecks geprüft, die FastMM4 gefunden hat. ;-)

Alex_ITA01 11. Sep 2013 09:21

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Alle Threads ausklammern wäre sicherlich recht aufwendig wenn überhaupt machbar. Muss ich mal im Hinterkopf behalten.

@jaenicke: Ich kann dir nur teilweise folgen. FastMM4 ist klar mit FullDebugMode, dann den Breakpoint auf die repeat until Schleife ist mir auch noch klar aber was meinst du mit "per Assemblerfenster manuell aus der Schleife und dann Speicherlecks prüfen"? Was du mit Assembler Fenster meinst weiß ich auch noch aber wie kommt ich "manuell" aus der Schleife um dann die Speicherlecks zu sehen?

Gruß
Alex

Edit: Könnte dieser Fehler auch von einem nicht freigegebenen Formular entstehen?

jaenicke 13. Sep 2013 19:54

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1227913)
Was du mit Assembler Fenster meinst weiß ich auch noch aber wie kommt ich "manuell" aus der Schleife um dann die Speicherlecks zu sehen?

Ich glaube da muss ich weiter ausholen, wenn ich die Frage lese. ;-)
Dazu habe ich gerade nicht genug Zeit, ich schreibe nachher etwas dazu.

Grundsätzlich musst du nur nach der Prüfung vor dem Sprungbefehl das Ergebnis manipulieren, damit du aus der Schleife kommst.

Zitat:

Zitat von Alex_ITA01 (Beitrag 1227913)
Edit: Könnte dieser Fehler auch von einem nicht freigegebenen Formular entstehen?

Klar, insbesondere wenn du es mit TMonitor nutzt.

Alex_ITA01 16. Sep 2013 07:15

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Hallo zusammen,

Zitat:

Zitat von Alex_ITA01:
Edit: Könnte dieser Fehler auch von einem nicht freigegebenen Formular entstehen?

Klar, insbesondere wenn du es mit TMonitor nutzt.
Ich selber nutze TMonitor definitiv nicht. Wenn dann ist das durch irgendwelche Änderungen im Hintergrund vom Delphi Standard reingekommen. Weiß denn jemand, ob TForm irgendwo neuerdings TMonitor benutzt?

@jaenicke:
Ich bin mal gespannt auf deine "Anleitung" mit dem Assemblerfenster ;-)

Gruß
Alex

jaenicke 16. Sep 2013 11:23

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Liste der Anhänge anzeigen (Anzahl: 1)
Oh, Entschuldigung, das habe ich vergessen.

Setze in die genannte Zeile (
Delphi-Quellcode:
repeat until AtomicCmpExchange(EventCache[I].Lock, 1, 0) = 0;
) einen Haltepunkt. Kommst du da an, öffne das CPU-Fenster (Strg + Alt + C), gehe weiter bis nach der Zeile
Delphi-Quellcode:
test eax, eax
, sprich in den bedingten Sprung jnz. Dann setze das Zero-Flag und du solltest aus der Schleife kommen.

Anhang 39873

Alex_ITA01 17. Sep 2013 12:21

AW: XE4 Probleme beim Beenden der Anwendung - DoneMonitorSupport
 
Danke schön. Werde ich mal testen und dann das Ergebnis hier bekannt geben.

Gruß
Alex


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:31 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-2025 by Thomas Breitkreuz