|
![]() |
|
Registriert seit: 29. Sep 2004 Ort: Jena 6 Beiträge Delphi 11 Alexandria |
#1
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) |
![]() |
Registriert seit: 3. Sep 2023 386 Beiträge |
#2
Hi
![]() was ist das und wo kommt das her?
![]() And above all: how can you prevent this?
Now to the discuss the call stack you provided: I can see the problem pinpoint it ![]() 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 If you had a decent logging you could have found it earlier, when forms/frames/modules report creation and destruction. Hope that helps.
Kas
|
![]() |
Registriert seit: 29. Sep 2004 Ort: Jena 6 Beiträge Delphi 11 Alexandria |
#3
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 |
![]() |
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.318 Beiträge Delphi 12 Athens |
#4
![]() Oops !! the code is trying to set focus to another form or a component
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")
Ein Therapeut entspricht 1024 Gigapeut.
Geändert von himitsu (28. Feb 2024 um 17:50 Uhr) |
![]() |
Registriert seit: 3. Sep 2023 386 Beiträge |
#5
Hi,
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. 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... So, first about logging: You don't need to log everything to a file, though logging everything and having the last few seconds of the life of an application before unexpected exception being raised is priceless, so what i would suggest is to build a log system that log to the memory instead of a file, in this case it is from the main thread, this will simplify the logging system as you don't need high performance and multithreaded logging system (could be a single class), more detail on this, (and as food for thought) for simple logging that can help you in this case: You will need a TStringList that store the log messages, as we talking main thread then we don't need SyncObjs like TCriticalSection or anything else, This list will reside in memory only, and when reaching some limit lets say 10k of lines, it will drop first 5k lines, and that is it, no ring buffer too, when an exception had being raised, then log the exception as usual and save that list (StringListLog) to a file, simple like that. What do you really need to log ?, the answer is simple : everything ! You don't need to do it in one go, but over time it will be great for GUi debugging and bug reporting, start with this case .., but in the future you can add anything with compiler directives or without !, just keep expand on that and never delete them, you can't kno when they are needed. Now to close look at the call stack : It is all starts with TMyComboBox.Destroy and this is very strange case, here comes to mind that either the captured stack is limited or the reporting tool had failed, so you need more or longer stack as much as you can get, i have no experience with MadExcept but i know for sure EurekaLog will and can capture the stack no matter what size is it, as long it is not corrupted. After this TMyComboBox.Destroy things get spicy, going through TElXPThemedControl, and this one although not familiar with by XP and theme trigger many memories for me, there was an is many software that hijack theming for windows or hook the interface for translation or whatever, these are the worst, worse than crazy and cheap AV, but this is not the case, and sorry for the ranting. Back on the track, first thing to caught the eye the FreeAndNil, this is your code coming from TElSBController.Destroy, the FreeAndNil reach this one TElSBHandlerCustom to destroy and here the first of checkpoint and crucial one to follow in detail in you logging, (in case you took the advice on logging), TElSBHandlerCustom.Destroy is blocking here in calling TElSBHandlerCustom.DestroyScrollTimer, so from what i see ScrollTimer responsible to destroy something (most likely TWomiTota), but instead of calling Free on it it send a message ! Now we can predict a path that can go wrong, remember that Windows in some cases can and might change the order of messages to deliver, also this information might not be relevant here, what is really relevant is this logic ![]() 00bae796 +05e My_Prog .exe Main 945 +14 TWomiTota.WndProc // another message
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 // a message handling coming form .Free somewhere, we except a cleaning up or just a notify We are here from freeing TElSBHandlerCustom then DestroyScrollTimer Now after all of that, is SetFocus really the cause of this exception ?, most likely no, not directly responsible for it anyway and more like a victim here, but the faulty logic is there and it happens to fail on SetFocus. What comes to mind and i had to ask : is there Application.ProcessMessages in any of the above walked code (orin a background thread), because if you are using it then i will blame it for this unpredictable behavior, Application.ProcessMessages is capable to generate nightmares. What you really should do is debug or rethink how and why that code is sending message (namely this TWomiTota class may even be recursively) while it is in pending Destroying a simple combobox. Hope that helps. ps: in case you will build a logging system always add ThreadID to the lines, it will pay when needed.
Kas
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |