Delphi-PRAXiS
Seite 1 von 2  1 2      

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


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:56 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz