17

I have an app which uses a keyboard hook procedure in a library. The wParam in the hook for one message is 255 which we think is "(reserved / OEMClear)". I'd like to work out the source of this message as it causes my application to crash in the library, and given it shouldn't be happening it would be good to identify it. The message comes in repeatedly on only one PC we have - other computers don't see the message at all.

So, is there a way to trace the source of a message sent to a window please, or all those on the system?

mj2008
  • 6,647
  • 2
  • 38
  • 56
  • The final solution for this, unfortunately, was a sticking plaster. I added another hook in my app which looks for this wParam value and doesn't call down the hook chain if matched. I'm making it PC specific (registry) but there seems to be something wrong with that PC. – mj2008 Jun 10 '09 at 10:36

4 Answers4

7

There is no built-in way to find out who sent the window message, not even win32k keeps track of this; you might be able to find it out with a kernel debugger and a conditional breakpoint.

However, I would argue that you don't really need this information; you need to make your app properly handle any message sent to it.

Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • 6
    I'd half agree - our purpose here is to find the cause, then we can judge the seriousness and handle it appropriately. I don't want to just stick a plaster over it in case it bites later, particularly as this is a commercial library that the fault fails in. – mj2008 May 26 '09 at 17:11
  • 1
    @mj2008: If you're deploying this to machines you don't fully control, you're going to get bitten; lots of badly-written apps send strange messages to all windows in attempts to do stuff and you *have* to deal with it elegantly. Just capture the messages you're interested in, and pass the rest along to the next hook in the chain. – Ana Betts May 26 '09 at 18:05
  • 2
    I' d suggest to add the sender id to the message. – Alpay Jan 10 '13 at 07:50
2

I came up with a technique for determining who is sending a win32 window message across threads/processes during one-off debugging/troubleshooting sessions. It requires making a couple of assumptions so it's not 100% reliable, but so far I haven't found a case where it didn't work.

The basic idea is to exploit the fact that, when the message arrives, the recipient window thread is typically blocked waiting in its message loop (specifically, GetMessage()). When the message is delivered, the sending thread readies the receiving thread, pulling it out of its wait state.

It turns out that Windows provides ways to precisely trace which threads are readying which other threads, using Event Tracing for Windows. Using this feature, it is often possible to determine which thread sent the message - it's the thread that readied the receiving thread. It's even possible to see what the call stack of the sending thread was at the time it sent the message, and even the kernel side (win32k) part of the stack!

The basic procedure goes like this:

  1. Use the Windows Performance Recorder to start a trace. Make sure to include the "CPU usage" profile.
  2. Trigger the sending of the message you are interested in.
  3. Stop the trace.
  4. Open the trace in the Windows performance Analyzer.
  5. In the "CPU Usage (Precise)" graph, "Stacks" graph preset, zoom in on the time the message was received.
    • One way is to locate the receiving thread and determine when it woke up.
    • If correlation is difficult, it might be worth instrumenting the receiving thread using e.g. TraceLogging to produce a clear reference time point.
  6. You should be able to find a context switch event where the receiving thread is readied in GetMessage.
  7. The "Readying Process", "Readying Thread Id" and "Readying Thread Stack" columns will then show the details of the readying thread, which is likely to be the sender of the message.

For example, in the below screenshot, TID 7640 receives a shell hook message originating from WindowsTerminal.exe, TID 1104:

WPA screenshot

Etienne Dechamps
  • 24,037
  • 4
  • 32
  • 31
1

(I originally suggested using Spy++ or winspector, but they do not hook into the sending of messages. That doesn't even make sense! A window receives messages but they don't send them, a thread does that. I'll leave my suggestion about using a debugger.)

Sometimes debugging can help. Try downloading the windows PDB files and setting a breakpoint that hits only when one of these messages occur. Looking at the call stack at that point can often shed some light on why things are happening. Posted messages and messages send from other processes will foil this approach.

Aardvark
  • 8,474
  • 7
  • 46
  • 64
  • I looked at Winspector first (used it for years) but it doesn't show the source. The debugger may be the only choice... – mj2008 May 26 '09 at 17:12
-3

Im not sure if this does what you want it to but have a look at Process Monitor by sysinternals.

http:// technet.microsoft.com/en-us/sysinternals/bb896645.aspx

It shows everything that happens to a process so i assume it catches messages as well. The site was down at time of writing so i couldnt check.

Ozzy
  • 10,285
  • 26
  • 94
  • 138
  • Thanks - it doesn't appear to trace messages, but it lead me to http://msdn.microsoft.com/en-us/library/cc267862.aspx which details the debug options in the debug build. But nothing there for message tracing either! – mj2008 May 26 '09 at 15:09
  • I don't see windows messages as an 'operation' in Process Monitor. – Aardvark May 26 '09 at 15:11
  • Process Monitor does not monitor [USER objects](https://learn.microsoft.com/en-us/windows/desktop/sysinfo/user-objects) (like windows). – IInspectable Jun 27 '19 at 08:26