AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Exception in IsFormSizeStored

Ein Thema von BlueStarHH · begonnen am 13. Apr 2021 · letzter Beitrag vom 28. Feb 2024
Antwort Antwort
Seite 1 von 2  1 2      
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
849 Beiträge
 
Delphi 11 Alexandria
 
#1

Exception in IsFormSizeStored

  Alt 13. Apr 2021, 12:13
Ich habe dieses Exception Log (Aufrufreihenfolge von unten nach oben) von einem Anwender:

exception class : EAccessViolation
exception message : Zugriffsverletzung bei Adresse 006DA5BF in Modul 'MeinProgramm.exe'. Lesen von Adresse 00000010.

Code:
006da5bf +00f MeinProgramm.exe Vcl.Forms               TCustomForm.IsFormSizeStored
006da5a5 +005 MeinProgramm.exe Vcl.Forms               TCustomForm.IsClientSizeStored
006dce58 +5a4 MeinProgramm.exe Vcl.Forms               TCustomForm.CreateParams
005d4700 +034 MeinProgramm.exe Vcl.Controls            TWinControl.CreateWnd
006d88f1 +005 MeinProgramm.exe Vcl.Forms               TScrollingWinControl.CreateWnd
006dced2 +00a MeinProgramm.exe Vcl.Forms               TCustomForm.CreateWnd
006e33e0 +024 MeinProgramm.exe Vcl.Forms               TApplication.ModalFinished
006e0062 +326 MeinProgramm.exe Vcl.Forms               TCustomForm.ShowModal
005d4d12 +016 MeinProgramm.exe Vcl.Controls            TWinControl.CreateHandle
005d8d90 +01c MeinProgramm.exe Vcl.Controls            TWinControl.HandleNeeded
005d8d9d +005 MeinProgramm.exe Vcl.Controls            TWinControl.GetHandle
006dfd2e +00e MeinProgramm.exe Vcl.Forms               TCustomForm.Release <--- hier !!!!
01992e72 +0b6 MeinProgramm.exe Main          4814      TMainDlg.ShowAbrechnungDlg
01989cbb +003 MeinProgramm.exe Main          2385      TMainDlg.acAbrechnungExecute

disassembling:
[...]
01992e62        pop    ecx
01992e63        mov    fs:[eax], edx
01992e66        push   $1992e7f
01992e6b 4814   mov    eax, [$1a3f2e4]
01992e70        mov    eax, [eax]
01992e72      > call   -$12b3157 ($6dfd20)   ; Vcl.Forms.TCustomForm.Release
01992e77        ret
01992e78        jmp    -$15880ad ($40add0)   ; System.@HandleFinally
01992e7d       jmp    loc_1992e6b
01992e7f 4820   xor    eax, eax
01992e81        pop    edx
[...]
Code:
procedure TMainDlg.ShowAbrechnungDlg;
begin
    Application.CreateForm(TAbrechnungDlg, AbrechnungDlg);
    try
      AbrechnungDlg.ShowModal;
    finally
      AbrechnungDlg.Release; <--- hier !!!!
    end;
end;

Wer kann helfen. Es sagt mir überhaupt nichts. Es scheint so, als ob eine Action (acAbrechnungExecute) ausgeführt wurde, die ein Fenster anzeigt (AbrechnungDlg). Nach dem Schleißen wird das Release (mit "hier" markiert) ausgeführt und ruft wieder ein ShowModal auf??? Das passiert direkt im VCL-Code. Nicht in meinem Code. Meine Unit ist nur die "Main".

Das Problem ist in mehr als 10 Jahren noch nie bei einem anderen Anwender aufgetreten und trat bei diesem Anwender bisher auch nicht wieder auf. Weitere Infos gibt es leider nicht.

Geändert von BlueStarHH (13. Apr 2021 um 12:19 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#2

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 13:06
Du solltest besser Free anstatt Release verwenden. Release sollte lediglich in den Events des Forms verwendet werden, da es die Freigabe verzögert. Das ist in deinem Fall aber nicht nötig und auch nicht erwünscht.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
849 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 13:48
Du solltest besser Free anstatt Release verwenden. Release sollte lediglich in den Events des Forms verwendet werden, da es die Freigabe verzögert. Das ist in deinem Fall aber nicht nötig und auch nicht erwünscht.
Ich bin seit Version 1 (1995?) bei Delphi dabei und habe das schon immer so gemacht. Ist mir wirklich in all den Jahren so ein Fehler unterlaufen? Generell vertraue ich auf Dein Wissen, Uwe. Danke! Bevor ich jetzt meinen gesamten Code umstelle, würde ich eine offizielle Quelle dafür schön finden. So weit ich weiss, arbeitet Release noch alle Messages ab, die anstehen. Kann das nicht wichtig sein?

Geändert von BlueStarHH (13. Apr 2021 um 13:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.070 Beiträge
 
Delphi 12 Athens
 
#4

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 13:49
Die VCL hat nach dem ShowModal das Windows-Control (HWND) der nicht mehr sichtbaren TForm bereits freigegeben.
Im Release wird aber auf das Handle zugegriffen *1 und weil es nicht mehr da ist, wird das Windows-Control neu erstellt, um danach erneut freigegeben zu werden.
Da gibt es wohl ein kleines Problemchen.

1) das Handle wird gebraucht, um dem Fenster eine Message zu schicken "gib dich frei", was aber erst "irgendwann" nach dem letzten END; ausgeführt wird, sobald die VCL jene Message verarbeitet.
Und Free gibt direkt frei, ohne unnötige Umwege.


Es passiert nicht immer, aber in der VCL ist es möglich die gekapselten Windows-Controls freizugeben, wenn sie nicht benötigt werden, um Systemressourcen zu sparen.
Und hier passiert es zufällig mal.
Das ist z.B. der Grund, warum manchmal Dinge "verschwinden", welche man selbst direkt über die WinAPI gemacht hat, weil beim Wiederherstellen die VCL davon natürlich nichts weiß.


Und warum für eine lokale Sache diese besch*** globalen Variablen benutzen?
Am Besten löscht man diese Variablen und kommt dann garnicht erst auf die Idee sie verwenden zu wollen.

Delphi-Quellcode:
procedure TMainDlg.ShowAbrechnungDlg;
var
  Dlg: TAbrechnungDlg;
begin
  Dlg := TAbrechnungDlg.Create(nil); // oder mit Self statt nil
  try
    Dlg.ShowModal;
  finally
    Dlg.Free;
  end;
end;

// ab 10.4
procedure TMainDlg.ShowAbrechnungDlg;
begin
  var Dlg := TAbrechnungDlg.Create(nil); // oder mit Self statt nil
  try
    Dlg.ShowModal;
  finally
    Dlg.Free;
  end;
end;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (13. Apr 2021 um 13:59 Uhr)
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
849 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 14:10
Das sagt die Delphi-Hilfe:

Code:
To free a form, call its Release method, which destroys the form and releases the memory allocated for it after all its event handlers and those of the components it contains are through executing.
Quelle: http://docwiki.embarcadero.com/Libra...m.TObject.Free
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.070 Beiträge
 
Delphi 12 Athens
 
#6

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 14:25
Wenn der Dialog nach dem Anzeigen Ausblenden keine "wichtigen" Messages mehr zu verarbeiten hat, dann ist ein Free OK und man als Entwickler weiß "JETZT ist es weg und nach mir kommt nichts mehr von diesem Objekt".


Der Dialog hat nicht zufällig sowas wie ein FreeOnClose?
Oder irgendwelche "komischen" Codes in OnCloseQuery, OnClose, OnHide, OnDeactivate, OnDestroy oder Dergleichen?
Hier sieht es ja fast so aus, als wenn das "ShowModal" nach/in dem Release nochmals neu aufgerufen würde.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
ECHTERNMM

Registriert seit: 29. Sep 2004
Ort: Jena
5 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Exception in IsFormSizeStored

  Alt 27. Feb 2024, 10:59
Hallo,

gibt es dazu irgendwelche neuen Erkenntnisse?

Wir verwenden immer schon free (nicht release), haben aber gelegentlich genau den gleichen Fehler.

Ich verwende eine Komponente, die von TCustomElComboBox abgeleitet ist: TMyComboBox; die ist eins der Controls der Form, die ich freigeben will. Ich habe den Destructor dieser Komponente "übernommen" (overload) und darin nichts anderes als

try
inheritted;
except
//meldung in Log-Datei schreiben
end;

eingebaut, aber, wie man sieht, wird der Destructor zwar ausgeführt, aber die Exception entsteht gar nicht in dieser Routine, obwohl der Stackdump (von Madexcept) das suggeriert.

Vielmehr schein Windows zu meinen, hier irgendwie eingreifen zu müssen:

7751507b +04b ntdll.dll KiUserCallbackDispatcher

was ist das und wo kommt das her?

Und vor allem: wie kann man das verhindern?


Man sollte noch wissen, dass diese Exception nicht reproduzierbar entsteht, sondern scheinbar zufällig ungefähr in 20 von 100 Fällen.

Gruß
MM



006cc0ef +00f My_Prog.exe Vcl.Forms TCustomForm.IsFormSizeStored
006cc0d5 +005 My_Prog.exe Vcl.Forms TCustomForm.IsClientSizeStored
006ce988 +5a4 My_Prog.exe Vcl.Forms TCustomForm.CreateParams
005c7550 +034 My_Prog.exe Vcl.Controls TWinControl.CreateWnd
006ca421 +005 My_Prog.exe Vcl.Forms TScrollingWinControl.CreateWnd
006cea02 +00a My_Prog.exe Vcl.Forms TCustomForm.CreateWnd
005c7b62 +016 My_Prog.exe Vcl.Controls TWinControl.CreateHandle
005cbbe0 +01c My_Prog.exe Vcl.Controls TWinControl.HandleNeeded
005cbbed +005 My_Prog.exe Vcl.Controls TWinControl.GetHandle
006cf205 +0f1 My_Prog.exe Vcl.Forms TCustomForm.SetFocusedControl
005c872f +21f My_Prog.exe Vcl.Controls TWinControl.WndProc
006ccc61 +64d My_Prog.exe Vcl.Forms TCustomForm.WndProc
00bae796 +05e My_Prog.exe Main 945 +14 TWomiTota.WndProc
005c8118 +02c My_Prog.exe Vcl.Controls TWinControl.MainWndProc
00543edc +014 My_Prog.exe System.Classes StdWndProc
0040f6b0 +20c My_Prog.exe System 168 +0 DynArraySetLength
7751507b +04b ntdll.dll KiUserCallbackDispatcher
005c3f66 +2be My_Prog.exe Vcl.Controls TControl.WndProc
005c8b4b +63b My_Prog.exe Vcl.Controls TWinControl.WndProc
006ccc61 +64d My_Prog.exe Vcl.Forms TCustomForm.WndProc
00bae796 +05e My_Prog.exe Main 945 +14 TWomiTota.WndProc
005c8118 +02c My_Prog.exe Vcl.Controls TWinControl.MainWndProc
00543edc +014 My_Prog.exe System.Classes StdWndProc
7751507b +04b ntdll.dll KiUserCallbackDispatcher
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil
00820ea3 +01b My_Prog.exe ElSBCtrl 3377 +2 TElSBHandlerCustom.DestroyScrollTimer
00820e63 +07f My_Prog.exe ElSBCtrl 3370 +9 TElSBHandlerCustom.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil
0082249b +017 My_Prog.exe ElSBCtrl 4165 +1 TElSBController.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00541bec +074 My_Prog.exe System.Classes TComponent.DestroyComponents
0054168b +01b My_Prog.exe System.Classes TComponent.Destroy
005c12d9 +121 My_Prog.exe Vcl.Controls TControl.Destroy
005c5dbf +16b My_Prog.exe Vcl.Controls TWinControl.Destroy
005cee90 +01c My_Prog.exe Vcl.Controls TCustomControl.Destroy
007d3544 +034 My_Prog.exe ElXPThemedControl 439 +3 TElXPThemedControl.Destroy
00842a1f +037 My_Prog.exe ElListBox 789 +4 TCustomElListBox.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00857ede +01a My_Prog.exe ElCombos 1626 +1 TCustomElComboBox.Destroy
00b3c80a +06a My_Prog.exe eboxen 2488 +10 TMyComboBox.Destroy

Geändert von ECHTERNMM (27. Feb 2024 um 11:11 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.
Online

Registriert seit: 3. Sep 2023
351 Beiträge
 
#8

AW: Exception in IsFormSizeStored

  Alt 27. Feb 2024, 11:32
Hi

Zitat:
was ist das und wo kommt das her?
Its usage in in the name, callback from the kernel, essential and everywhere, in essence it is you main thread loop origin.

Zitat:
And above all: how can you prevent this?
If you are talking about KiUserCallbackDispatcher, then the answer is no you can't prevent passing or remove it from your application logic using GUI.

Now to the discuss the call stack you provided:

I can see the problem pinpoint it
Zitat:
006cc0ef +00f My_Prog.exe Vcl .Forms TCustomForm.IsFormSizeStored
006cc0d5 +005 My_Prog.exe Vcl .Forms TCustomForm.IsClientSizeStored
006ce988 +5a4 My_Prog.exe Vcl .Forms TCustomForm.CreateParams
005c755 0 +034 My_Prog.exe Vcl .Controls TWinControl.CreateWnd
006ca421 +005 My_Prog.exe Vcl .Forms TScrollingWinControl.CreateWnd
006cea02 +00a My_Prog.exe Vcl .Forms TCustomForm.CreateWnd
005c7b62 +016 My_Prog.exe Vcl .Controls TWinControl.CreateHandle // Creating Handle for most likely already freed parent or owner
005cbbe0 +01c My_ Prog.exe Vcl .Controls TWinControl.HandleNeeded
005cbbed + 005 My_Prog.exe Vcl .Controls TWinControl.GetHandle // GetHandle
006cf205 +0f1 My_Prog.exe Vcl .Forms TCustomForm.SetFocusedControl // <----- Oops !! the code is trying to set focus to another form or a component !!
005c872f +21f My_Prog.exe Vcl .Controls TWinControl.WndProc
006ccc61 +64d My_Prog.exe Vcl .Forms TC ustomForm.WndProc
00bae796 +05e My_Prog .exe Main 945 +14 TWomiTota.WndProc
005c8118 +02c My_Prog.exe Vcl .Controls TWinControl.MainWndProc
00543edc +014 My_Prog.exe System.Classes StdWndProc
0040f6b0 +20c My_Prog.exe System 168 +0 DynArraySetLength
7751507b +04b ntdll.dll KiUserCallbackDispatcher
005c3f66 +2be My_Prog.exe Vcl.Controls TControl.WndProc
005c8b4b +63b My_Prog.exe Vcl.Controls TWinControl.WndProc
006ccc61 +64d My_Prog.exe Vcl.Forms TCustomForm.WndProc
00bae796 +05e My_Prog.exe Main 945 +14 TWomiTota.WndProc
005c8118 +02c My_Prog.exe Vcl.Controls TWinControl.MainWndProc
00543edc +014 My_Prog.exe System.Classes StdWndProc // <------- more messages after the destruction
7751507b +04b ntdll.dll KiUserCallbackDispatcher
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free // <------- last free before end the destruction
00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil
00820ea3 +01b My_Prog.exe ElSBCtrl 3377 +2 TElSBHandlerCustom.DestroyScrollTimer
00820e63 +07f My_Prog.exe ElSBCtrl 3370 +9 TElSBHandlerCustom.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil
0082249b +017 My_Prog.exe ElSBCtrl 4165 +1 TElSBController.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00541bec +074 My_Prog.exe System.Classes TComponent.DestroyComponents
0054168b +01b My_Prog.exe System.Classes TComponent.Destroy
005c12d9 +121 My_Prog.exe Vcl.Controls TControl.Destroy
005c5dbf +16b My_Prog.exe Vcl.Controls TWinControl.Destroy
005cee90 +01c My_Prog.exe Vcl.Controls TCustomControl.Destroy
007d3544 +034 My_Prog.exe ElXPThemedControl 439 +3 TElXPThemedControl.Destroy
00842a1f +037 My_Prog.exe ElListBox 789 +4 TCustomElListBox.Destroy
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free
00857ede +01a My_Prog.exe ElCombos 1626 +1 TCustomElComboBox.Destroy
00b3c80a +06a My_Prog.exe eboxen 2488 +10 TMyComboBox.Destroy
I may be wrong but from what i see it is a SetFocus called without checking for free/exiting...
If you had a decent logging you could have found it earlier, when forms/frames/modules report creation and destruction.

Hope that helps.
Kas
  Mit Zitat antworten Zitat
ECHTERNMM

Registriert seit: 29. Sep 2004
Ort: Jena
5 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Exception in IsFormSizeStored

  Alt 28. Feb 2024, 17:06
Hi,

Thank you for your hints, but its difficoult to determin, where the strange SetFocus-Message come from.

The Problem is, that - as already mentioned by BlueStarHH - it does not occur for years but suddenly now.

There is a process, that is repeated - say 100 times a day - on the same machine, same user, same setting, but in about 20 cases the error occur, in about 80 cases not.

On mine own machine I could not reproduce it at all.

There are also other machines, where it occur only once a month or so, nevertheless, they use it also many times a dayx.

It looks like, thats a strange Windows probnlem, because machines, where it occur more often, are updated recently,

What do you mean by "decent logging"? Shall I catch all setfocus messages and write them to a logfile?

But that would also not show, where they come from...

Regards
MM
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.070 Beiträge
 
Delphi 12 Athens
 
#10

AW: Exception in IsFormSizeStored

  Alt 28. Feb 2024, 17:34
Zitat:
Oops !! the code is trying to set focus to another form or a component
Wenn die Komponente/Form freigegeben wird, welche aktuell den Focus besitzt, dann wird der Focus an den Nächsten weitergegeben.

Verliert eine Anwendung komplett den Fokus, dann verliert sie die Eingabekontrolle und wird von Windows in den Hintergrund verschoben. (hinter Fenster anderer Anwendungen)

z.B. beim Anzeigen eines Dialogs oder ShowModal einer Form, merkt sich Delphi welches Fenster aktuell vorher aktiv war
und beim Close wird versucht an jenes Fenster den Fokus "zurück" zu übergeben ... besonders gut funktioniert das, wenn dieses Fenster inzwischen auch nicht mehr existiert oder nicht fokusierbar ist.



Wurde das SetFocus durch ein PostMessage ausgelöst, dann kann man den Sender eh nicht mehr rausbekommen, welcher das vor einer "Weile" in die MessageQueue schrieb.

Beim SendMessage wäre es eigentlich möglich, aber der Stacktrace im GetMessage/PeekMessage verläuft sich gern und dann bricht der Stack meistens mittendrin ab, so dass man da auch nichts sieht.

Wurde der Focus durch eine programmseitige Aktion in der VCL ausgelöst, also durch Aufruf von Control.SetFocus oder Zuweisung an Form.ActiveControl bzw. Screen.ActiveControl oder beim Wechsel der VCL-Forms, dann sollte man die Stelle im Debugger/Stacktrace finden können, was aber auch nicht immer funktioniert.
Leider gibt es nicht nur ein einziges SetFocus und sie nutzen keine gemeinsamme, globale Funktion, so dass man nur die DebugDCUs in den Projektoptionen aktivieren kann und dann auf "alle" SetFocus einen Haltepunkt setzen müsste.



Ich wollte mal "dem" SetFocus beibringen den Namen der VCL-Komponente in die Fehlermeldung zu schreiben, damit man wenigstens das Ziel erfährt und nicht nur sowas wie "Ein inaktives Control kann keinen Focus erhalten", weil irgendwo ein SetFocus aufgerufen wird, obwohl das Control, ein Parent oder die Form disabled oder invisible sind.
Das war echt ein Vorhaben, wo man fast nur aufgeben kann. (und Emba sich weigert dieses Verhalten zu "reparieren")
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (28. Feb 2024 um 17:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:30 Uhr.
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