I have a delphi 2007 application that is having periodic access violations in TControl.Perform method from the standard VCL unit Controls.pas. The call stack looks like this:
exception message : Access violation at address 00000000. Read of address 00000000.
Main ($1cac):
00000000 +000 ???
004cd644 +024 mainexe.exe Controls 5021 +5 TControl.Perform
004ce705 +015 mainexe.exe Controls 5542 +2 TControl.CMMouseEnter
004cd9b7 +2bb mainexe.exe Controls 5146 +83 TControl.WndProc
004d19bb +4fb mainexe.exe Controls 7304 +111 TWinControl.WndProc
004a8ff8 +06c mainexe.exe StdCtrls 3684 +13 TButtonControl.WndProc
004cd644 +024 mainexe.exe Controls 5021 +5 TControl.Perform
004d182b +36b mainexe.exe Controls 7255 +62 TWinControl.WndProc
004a8ff8 +06c mainexe.exe StdCtrls 3684 +13 TButtonControl.WndProc
004d10e4 +02c mainexe.exe Controls 7073 +3 TWinControl.MainWndProc
0048af08 +014 mainexe.exe Classes 11583 +8 StdWndProc
75ce7bc5 +00a USER32.dll DispatchMessageA
004ecaf4 +0fc mainexe.exe Forms 8105 +23 TApplication.ProcessMessage
004ecb2e +00a mainexe.exe Forms 8124 +1 TApplication.HandleMessage
004ece23 +0b3 mainexe.exe Forms 8223 +20 TApplication.Run
0136cac7 +383 mainexe.exe mainexe 326 +45 initialization
75563398 +010 kernel32.dll BaseThreadInitThunk
I am unable to reproduce it in the office, so I only get the call stacks from customers directly, via MadExcept.
I am not sure how to diagnose or otherwise determine the cause, and then correct a fault that occurs this way. I'm hoping someone has seen this "TControl.Perform" style of access violation, and has some idea on the root causes.
My #1 suspicion is that a form has been "freed" by some other area of my code, and that a window message is being processed, and that TControl (as a base class of some real control in some real form) is simply failing because Self is nil, or some resource like the window handle is invalid.
I'm looking for a technique that will help me diagnose this problem, that can be executed on a client's computer, without access to the delphi debugger. Thoughts I've had include adding some logging (but what?) or even running WinDbg (the windows SDK debugger tool) on the client's machine.
WindowProc
. What this means is that you have aTControl
instance for whichWindowProc
isnil
. Something very bad has gone wrong. – David HeffernanTButtonControl
descendant handlingWM_MOUSEMOVE
message, seeTWinControl.WndProc
. It looks like the problem is with the parent of the button control (seeTControl.CMMouseEnter
line 5542) - for some reason itsWindowProc
is nil. Perhaps you're using theWindowProc
property for subclassing but are not replacing the original properly? This can also easily happen if subclassing multiple times but restoring original methods in wrong order... – Ondrej KelleFree
called when aRelease
should be used. (I had such a case at a previous company with some stinking mix ofFree
-instead-of-Release
andProcessMessages
) – Francesca