3

Periodically getting an access violation from a PeekMessage. This is not my call to PeekMessage, it's from Application.Run. Stack trace from MadExcept shows Application.Run calling PeekMessage which in turn is calling kiUserCallBackDispatcher.

Delphi 2009.

Stack trace is:

callstack crc     : $0202d0d7, $a09d5671, $3195cde5
exception number  : 1
exception class   : EAccessViolation
exception message : Access violation at address 0202D0D7. Write of address 00310038.

main thread ($1650):
0202d0d7 +000 ???
7c90e470 +010 ntdll.dll                               KiUserCallbackDispatcher
7e4193fd +162 USER32.dll                              PeekMessageW
0050b2a4 +01c infraWrapper90.exe Forms                TApplication.ProcessMessage
0050b3ea +00a infraWrapper90.exe Forms                TApplication.HandleMessage
0050b715 +0c9 infraWrapper90.exe Forms                TApplication.Run

I assume this means that PeekMessage() is making a call to one of one my Window Procedures to process a message, and it can't find that Window procedure. At first I didn't see why Peekmessage would be calling any window procedure as it is just peeking at messages but from futher reading on here and elsewhere I think I see that:

  • PeekMessage() will process SendMessages() sent from other threads
  • PeekMessage() will sometimes handle Paint messages
  • Someone else has reported seeing PeekMessage calling a Window procedure for other messages, such as WM_ERASEBKGND.

From MSDN:

During this call, the system delivers pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function.

Which I don't quite understand as I thought SendMessage() calls were handled immediately. Someone else seemed to think this only applied when the SendMessage was from another thread.

I can't duplicate this in a stand alone project. From the error it appears as if PeekMessage is calling a Window Procedure which no longer exists - but I've tried doing this myself by intentionally destroying a form then doing a SendMessage() and Postmessage() to an invalid window handle and Windows just seems to ignore it. I've tried posting messages from a form's destructor to itself and all sorts of other things but I can't get it to fail.

Any suggestions as to anything else to check? Thanks in advance.

Rick

Martijn
  • 13,225
  • 3
  • 48
  • 58
RBrowning99
  • 411
  • 2
  • 9
  • 21
  • "Which I don't quite understand as I thought SendMessage() calls were handled immediately. Someone else seemed to think this only applied when the SendMessage was from another thread." Well, `SendMessage` calls have to be executed in the context of the thread that owns the window. You can't just inject code into a running thread at any random point. So the mechanism is to use calls to routines like PeekMessage, GetMessage etc. to dispatch the non-queued messages. – David Heffernan Jul 11 '12 at 09:45
  • I think you basic analysis is correct though. By far the most likely scenario is that the message is being sent to a window that is no longer there. – David Heffernan Jul 11 '12 at 09:46
  • I would suppose that `LPMSG` argument to the function pointed to invalid address. You can check this easily by catching the exception and checking the pointer. With a wrong (closed) handle it should have been an error code rather than access violation. – Roman R. Jul 11 '12 at 10:19
  • @RomanR. That's not it. The `LPMSG` points to a local variable in `TApplication.HandleMessage`. – David Heffernan Jul 11 '12 at 10:40
  • 1
    "Write of address 00310038"? Perhaps you have a string containing "81" that you're treating as an address. – Rob Kennedy Jul 11 '12 at 11:52
  • Thanks for the comments. Yes, I see why SendMessage() from another thread must be executed by the thread which owns the window the message was sent to. It was the MSDN help I didn't really understand as I thought it was implying that all sendmessages were being processed this way - but I suppose the key is where it says "pending nonqueued messages". Sendmessages to a window handle in the same thread would not be pending would they? I think the help could be a bit clearer on this but regardless we're in agreement. Of coure the problem now is why we get the access violation. – RBrowning99 Jul 11 '12 at 19:32
  • I don't think the app. has any cross thread SendMessages so that leaves me thinking that this is in response to a PostMessage - and my stand alone tests show that Postmessages to invalid window handles are ignored. At some stage Windows must think this is a valid handle but it has an invalid Window procedure pointer. Any suggestions on where to look next? The code is not assigning Window procedures dynamically. Thanks – RBrowning99 Jul 11 '12 at 19:34
  • No hint from what module is based about 02020000? (can use modules window). – Sertac Akyuz Jul 11 '12 at 20:07
  • 1
    Is it possible that the window proc resides in a DLL that has been unloaded? – David Heffernan Jul 11 '12 at 20:53
  • @sertac Since madExcept can't identify the module that owns the code, surely that's because there is no module there. – David Heffernan Jul 11 '12 at 20:55

0 Answers0