Well, i only can say what comes to mind and from what see here, and while i don't have and didn't use anything after XE8, i saw lot of these from Delphi 2009, 2010 and XE8 (with few in between and before)
So,
As for the "some thread is hanging in the Synchronize", this is classic failure in clean up, the thread is blocking (hanging in this case) in DoTerminate, waiting for the main thread to release it, yet the release will never come.
With classic failure in clean up, i meant in this case the failure not in code but in the structure and logic, the failure to predict breaking point and allowing race condition, clean up was done in the code half assed, removed from part and left in other
package/library... that thread was created at some point from the main, but a clean/refactor messed the structure and left it without connection to the main thread loop, in this case and because DoTerminate calling an assigned event OnTerminate, and this most likely belongs to an already unloaded
package or again the main thread is lost for it, in other words WakeMainThread is not there, and it will be there waiting for specific signal that will never come,..
This happen when you build a library to be used with Windows Service or may be in Console application, where main thread has different main loop (or wait state) and it in theory should not fail, but when tangling so many of these then all what needed is one small
exception throwing main thread waiting on already the waiting signal, and you left with freezing application.
to get better diagnose for this case, you need to track it and remove, but how ? you said you have no idea who started this one,
It is easier if you look at this in light form different angle, ( and that why i hate anonymous methods specially if they attached to threads), you have to monitor the creation of all threads and their calling stacks before reaching this point then find the caller/creator, use real debugger with trace like x64dbg
https://x64dbg.com/ or any tracing/tracking/monitoring tool like ApiMonitor to track CreateThread and identify it by
Handle, the tool should/must capture the stack (even Procoss Monitor from SysInternals can capture CreateThread with calling stack).
As for the main dish and you main question:
Zitat:
:77d4b66f ntdll.KiUserExceptionDispatcher + 0xf
rtl.System._DynArraySetLength
:6dde6a8e @DynArraySetLength + $A
:6ed92b18 ; C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\coreide290.bpl
:6ed88574 ; C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\coreide290.bpl
:6ed88b7b coreide290.@Editorcontrol@TCustomEditControl@EdRef resh$qqro + 0x57
:6edab6e3 ; C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\coreide290.bpl
:6edac28f coreide290.@Kbclient@TIDEKBDChildAPI@ProcessKeyStr oke$qqriiii + 0xa3
:6ed971d2 ; C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\coreide290.bpl
:6ed86e5b coreide290.@Editorcontrol@TCustomEditControl@CNKey Down$qqrr22Winapi@Messages@TWMKey + 0x9f
I don't know what is Editorcontrol is, i can remember if i saw it in my IDEs, and not sure if this is CustomEdit derived or TMemo or something else, but clearly it did capture the CNKeyDown message then reached ProcessKeyStroke which called EdRefresh and from there SetLength lead to an
exception.
How to unpack this ? well, it is not easy at all because we are missing huge chunks from the big picture.
So thoughts here, and i am sorry they are less helpful but might give you some insights if you want to dig deeper into this
1) The most important and clearest thing is the many failures of the
exception handling in the
IDE which Embarcadero keep using and trusting of the blue, the Jcldebug , why ? who knows, there is way better two tools and could have helped filtering and fixing all this crab years ago, yet they keep implementing their own based on outdated codes, using MadExcept or EurekaLog could helped capture better call stacks and even stopping this from happening, enough ranting and lets back to the failures.
A) Some calls resolved and some is not, seen from coreide290, this is functionality failure and it is enough to be not used at all.
B) Failure to correctly
handle HandleAnyException, which is ... well ... will come to this later because it is the crucial point in this case.
C) The consistent and known failure to display
Exception Dialog when the main thread is f*****, see MadExcept and EurekaLog neatly build to separate these dialog from the main thread, the current
exception handling in
IDE is known and there for decades, on the contrary a simple not to re-raise and just not show a dialog in could solved/reduced the freezing or silent crashing, they could (well if they have spare time from adding huge features like ternary...) and just add a feature to generate a simple file
exception logging instead of dialog and suppress the dialogs altogether, they themselves could have way better reports to fix the
IDE.
2) We have EditCOntrol that capture and
handle WM_KEY message, then it leads to refresh, between these two a focus lost or changed could caused havoc, specially events in
VCL by default use Sender as generic, so a missed check to ensure the code is still executing on the same control could caused this, from what i understand the newer
IDE can show multiple editor, and that if we talking about what you were doing when this went south, the key pressed was in the code editor ? or some of the newer search editor ? or something else
See, i write with many errors (typos) and go fix them, like the above, i wrote EditCOntrol instead of EditControl, and always (most of the time) go back and fix them, this caused by things, like what i doing while writing, like answering phone, or thinking of different part of the code while writing some elsewhere..or... doesn't matter it caused by fraction of second that i held my left Shift key down by my left pinky, problem with coordination may be, the thing is what you do when you hit a key with another key in some small time period a key that might switch focus ?! there is so many combination of shortcuts, and we as human might not notice how this happen, this can be a reason, but it is failure in the
IDE none the less, only way harder to reproduce, the
IDE and the editor and its memory manager should be under some stress while background thread doing something.
3) the unresolved calls from the same freaking
IDE that shipped this
exception handling is so annoying, that i can't believe the developers can find exceptions or even care to find them to begin with, how they should understand what it is going on, or they are super duper developers that don't make mistakes and don't miss anything... it is mind boggling.
4) The fact of a key press coming form Windows message leading to a refresh is hard for me to imagine, well i have vivid imagination, and yes i can imagine many scenarios for going from key press to directly call a procedure/function called EdRefresh, but is this logically correct to do, Refresh what ? a visual content refresh usually you call that with a message, right ? not direct call, you are short circuiting here, are you refreshing the internal content without updating ? then yes it is possible and should have better name, yet this should very easy to protect against and again mind boggling to lead to a an
exception in adjusting an array length, right ? yes i am right here!.
5) The failure to resolve stack, is ... (SNIPPED more ranting) .. , see ,if we only knew what that address 6ed92b18 in coreide290.bpl resolve to and the line, it will be huge difference in understanding the bug and solve it, once and for all, is it in the compiler added magic ? is it in finally..end ? is it in the terminating and cleaning up of that procedure.. , each one will point to a direction, but in any direction you will be able to solve this, this bug should be as easy to fix as it get, like never easier, but the lack of the stack of the last two calls before SetLegnth makes it harder even for the developer themselves who can simply check in debugged
IDE with sources and find the issue.
6) Back the crucial moment in this case, HandleAnyException this triggered because the code either :
A) doesn't have one try..except between WM_KEY to that EdRefrsh, leading to escaping/running
exception, handled centrally and waiting on already waiting main thread.
B) handled, and done badly with very frustrating design i saw so many developer keep doing it, which is capture an
exception then re-raise it, to all i say, good people stop doing that, it might work now and when you thought about it, but the risk of failure in future is so high that you are rigging a bomb waiting one refactor or reuse of the code/
unit.
So this freeze you seeing is very simple to solve by simply try..except and .. that is it, just don't re-raise the thingy.
In case you want to
handle it right then generate/output some log before showing a dialog, how hard it is to do that.
7) The fact that the
IDE freezes with SleepEx coming form borlndmm.dll (the memory manager) is so strange, so, what memory manager is used ? and how much it is out dated ? are the questions here.
Sorry for the long post, and the ranting, i have guests and writing this post and received 4 phone calls, two of them caused too much of brain capacity and they have nothing to do with digital world but with the real life and why there will not be water for 10 hours, but .. anyway i will not suggest to you to stop researching or digging into the
IDE, on the contrary i love investigative work, they do widen one mental capacity and teach from others mistakes, so if you want to continue then use Ghidra or IDA to try and figure these unresolved addresses, yet even that then ruined it by not using their own TDInfo and switching to different debug information and no one outside Delphi world can
handle, so .. you can put a parser for its debug information using JCL (assuming they are still using the same one and not modified version)
Hope you find that helpful, and good luck !