Windows Kernel Debugging - get the address of thread's message queue?

I’d like to monitor the content of an application’s main thread’s message queue, but I have no idea how to get the address of it (WinDbg, kernel debugging). Would anyone have a hint for me? The thing is, when our main thread stays in WaitForSingleObject for a longer period of time, we get sometimes “Not enough quota…” when calling PostMessage afterwards. It’s clear to me it’s about the message queue being overflowed, but I cannot find out (with Spy++) who posts so many messages to the main thread in the meantime.

And no, I can’t change the awful design at the moment :slight_smile: I know the main thread mustn’t be used for waiting long for an event, but as I said - I can’t change it in the next months.

I’d like to find out what messages overflow the queue, and my second idea (the first was Spy++) is to watch the main thread’s message queue.

Perhaps there are other good ideas?

Regards, Maciej

iam not sure if i understand you correct

but if you want to debug an user mode application it is better to use
windbg directly instead of using kernel debugging as handling
usermode applications from a kernel mode debugger involves quiet a bit
of jugglery

you have to run a local debugger in the client and redirect the output
to kernel debuggier running on host

for example ntsd -d “your app.exe” will redirect output to a kd
running in host

and you should be in right process context when you want to do
something in kernel debugger for that process

but if you are just interested in user mode debugging just

use windbg “your app.exe” “your apps args” to create

or attach to a running instance of “your app” using
windbg -pn “your app” //
windbg -p pid

etc

and when you have broken in

you can set a breakpoint on DispatchMessage / TranslateMessage apis in
user32.dll
and inspect the messages using dd db etc

if you want a formatted output you can download ken johnsons
(skywing’s) sdbgext
extension

and use the !usermsg extension command you can also use grep etc to
filter the out put further

see paste below for a simple msgpump loop

0:001> .load sdbgext
0:001> !sdbgext.usermsg
Usage: !usermsg


0:001> bp user32!DispatchMessageA "!usermsg poi(esp+4);g"
0:001> bl
0 e 7e4196b8 0001 (0001) 0:****user32!DispatchMessageA
"!usermsg poi(esp+4);g"
0:001> g
hwnd:
Window 000602f8
Name Our First Window
Class SimpleWinClass
WndProc 00000000
Style WS_OVERLAPPED
ExStyle WS_EX_WINDOWEDGE WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR
HInstance 00400000
ParentWnd 00000000
Id 00000000
UserData 00000000
Unicode FALSE
ThreadId 00000944
ProcessId 00000940
Message: 0x0112
wParam: f120
lParam: 0
Time: 29217a
pt: (164, 507)
hwnd:
Window 000602f8
Name Our First Window
Class SimpleWinClass
WndProc 00000000
Style WS_OVERLAPPED
ExStyle WS_EX_WINDOWEDGE WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR
HInstance 00400000
ParentWnd 00000000
Id 00000000
UserData 00000000
Unicode FALSE
ThreadId 00000944
ProcessId 00000940
Message: 0x0112
wParam: f120
lParam: 0
Time: 29217a
pt: (164, 507)
hwnd:
Window 000602f8
Name Our First Window
Class SimpleWinClass
WndProc 00000000
Style WS_OVERLAPPED
ExStyle WS_EX_WINDOWEDGE WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR
HInstance 00400000
ParentWnd 00000000
Id 00000000
UserData 00000000
Unicode FALSE
ThreadId 00000944
ProcessId 00000940
Message: 0x0101
wParam: d
lParam: c01c0001
Time: 2922c3
pt: (164, 507)

using domdbg extension and using grep on the output to filter only messages

0:001> bp user32!DispatchMessageA "!grep -e \"Message:\" -c \"!usermsg
poi(esp+4)\";g"
breakpoint 0 redefined
0:001> bl
0 e 7e4196b8 0001 (0001) 0:**** user32!DispatchMessageA "!grep
-e \"Message:\" -c \"!usermsg poi(esp+4)\";g"
0:001> g

Message: WM_PAINT
Message: 0x0113
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200
Message: 0x0200

On 5/15/12, xxxxx@gmx.de wrote:
> I'd like to monitor the content of an application's main thread's message
> queue, but I have no idea how to get the address of it (WinDbg, kernel
> debugging). Would anyone have a hint for me? The thing is, when our main
> thread stays in WaitForSingleObject for a longer period of time, we get
> sometimes "Not enough quota..." when calling PostMessage afterwards. It's
> clear to me it's about the message queue being overflowed, but I cannot find
> out (with Spy++) who posts so many messages to the main thread in the
> meantime.
>
> And no, I can't change the awful design at the moment :) I know the main
> thread mustn't be used for waiting long for an event, but as I said - I
> can't change it in the next months.
>
> I'd like to find out what messages overflow the queue, and my second idea
> (the first was Spy++) is to watch the main thread's message queue.
>
> Perhaps there are other good ideas?
>
> Regards, Maciej
>
>
> ---
> WINDBG is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Right! Thanks for the hint, I forgot about the simplest way - the message queue must be processed by a message loop once the thread is released. It definitely helped me to continue debugging the issue.

But out of pure curiosity back to the original question - is there a way to find out where a thread’s message queue is?

Regards,
M

again i am not sure if i understand you correct

the threads message queues are system defined memory objects and are
created by the system if it deems that that there is a message queue
requirement

not all threads are created with a message queue as such

  1. i am not sure if you can query for a threads message queue address

2 ) also you cant find who posted the message to your threads message queue

all you can know is you have a message in your queue and you can
decide what to do with it because you got a MSG struct filled up with
details

it is a dead letter drop box as they say in spy++ thrillers

you run an infinte loop and sit waiting for system to hand you your message

system fills up the MSG struct when you call GetMessage() PeekMessage() etc

or you can use GetQueueStatus() etc to get a hint of the contents of
message queue

also iirc there is a registry key which you can modify to increase the
size of message queue which has a default value of 10000 messages per
message queue

if you are interested in internal implementation details then you can
try deciphering the

XXX calls :slight_smile: in win32k.sys like xxxscansysqueue() xxxAllocQueue() etc

On 5/15/12, xxxxx@gmx.de wrote:
> Right! Thanks for the hint, I forgot about the simplest way - the message
> queue must be processed by a message loop once the thread is released. It
> definitely helped me to continue debugging the issue.
>
>
> But out of pure curiosity back to the original question - is there a way to
> find out where a thread’s message queue is?
>
> Regards,
> M
>
> —
> WINDBG is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

lkd> dt nt!_KTHREAD Win32Thread @@masm($thread)
+0x130 Win32Thread : 0xe434add0 Void
lkd> dt win32k!_W32THREAD 0xe434add0
+0x000 pEThread : 0x85e7e350 _ETHREAD
+0x004 RefCount : 1
+0x008 ptlW32 : (null)
+0x00c pgdiDcattr : (null)
+0x010 pgdiBrushAttr : (null)
+0x014 pUMPDObjs : (null)
+0x018 pUMPDHeap : (null)
+0x01c dwEngAcquireCount : 0
+0x020 pSemTable : (null)
+0x024 pUMPDObj : (null)
lkd> ? @@masm($thread)
Evaluate expression: -2048400560 = 85e7e350

beyond 24 there are several undocumented fields which contains the
message queue implementation details for example
win32k!_getQueueStatus will play with +0x38

there is an old userkdx.dll extension in windows2000 folder which can
show some of these presently fields but that extension is valid only
upt0 w2k and in > xp it can yield errenous results

lkd> !dti e434add0

*** Extension DLL(2167 Free) does not match target system(2600 Free)

et 0x85e7e350 t 0x??? q 0x??? i 0.85e7e534
PTHREADINFO @ 0xE434ADD0
PtiLink.Flink @0x000000B0
ptl @0x00000000
ptlW32 @0x00000000
ppi @0x00000000
pq @0x00000000
spklActive @0x00000000
mlPost.pqmsgRead @0x00000000
mlPost.pqmsgWriteLast @0x00000000
mlPost.cMsgs 0x00000000
spwndDefaultIme @0x00000000
spDefaultImc @0x00000000
hklPrev 0x00000000
rpdesk @0xE4425760
hdesk 0x00000000
amdesk 0x00000000
pDeskInfo @0xE2B7F1F8
pClientInfo @0xBBE9CC28
TIF_flags TIF_ALLOWFOREGROUNDACTIVATE |
TIF_ALLOWOTHERACCOUNTHOOK | TIF_DELAYEDEVENT | TIF_DISABLEIME |
TIF_DONTATTACHQUEUE | TIF_DONTJOURNALATTACH | TIF_DOSEMULATOR |
TIF_GLOBALHOOKER | TIF_GUITHREADINITIALIZED | TIF_INACTIVATEAPPMSG |
TIF_MSGPOSCHANGED | TIF_SHUTDOWNCOMPLETE | TIF_SPINNING |
TIF_TRACKRECTVISIBLE | TIF_VDMAPP | TIF_WAITFORINPUTIDLE | TIF_WOW64 |
0x80000000
sphkCurrent @0x00000000
pEventQueueServer @0x00000000
hEventQueueClient 0x00000000
fsChangeBits QS_KEY
fsChangeBitsRemovd 0
fsWakeBits 0
fsWakeMask QS_MOUSEBUTTON
cPaintsReady 0x0000
cTimersReady 0x0038
timeLast 0x00000000
ptLast.x 0xe148751c
ptLast.y 0x00000000
idLast 0x00000000
cQuit 0x00000000
exitCode 0x00000000
pSBTrack 0x00000000
psmsSent @0x7FFDC6CC
psmsCurrent @0x01000020
fsHooks 0xe437a008
aphkStart @0xE434AEBC l16
sphkCurrent @0x00000000
psmsReceiveList @0x00000000
ptdb @0x00000000
Thread @0x85E7E350
PriorityClass 0
cWindows 0x00000000
cVisWindows 0x000f01ff
pqAttach @0x00000000
iCursorLevel 0xe437a0b4
pMenuState @0x00000000

On 5/15/12, raj_r wrote:
> again i am not sure if i understand you correct
>
> the threads message queues are system defined memory objects and are
> created by the system if it deems that that there is a message queue
> requirement
>
> not all threads are created with a message queue as such
>
> 1) i am not sure if you can query for a threads message queue address
>
> 2 ) also you cant find who posted the message to your threads message queue
>
> all you can know is you have a message in your queue and you can
> decide what to do with it because you got a MSG struct filled up with
> details
>
> it is a dead letter drop box as they say in spy++ thrillers
>
> you run an infinte loop and sit waiting for system to hand you your message
>
> system fills up the MSG struct when you call GetMessage() PeekMessage()
> etc
>
> or you can use GetQueueStatus() etc to get a hint of the contents of
> message queue
>
> also iirc there is a registry key which you can modify to increase the
> size of message queue which has a default value of 10000 messages per
> message queue
>
> if you are interested in internal implementation details then you can
> try deciphering the
>
> XXX calls :slight_smile: in win32k.sys like xxxscansysqueue() xxxAllocQueue() etc
>
>
> On 5/15/12, xxxxx@gmx.de wrote:
>> Right! Thanks for the hint, I forgot about the simplest way - the message
>> queue must be processed by a message loop once the thread is released. It
>> definitely helped me to continue debugging the issue.
>>
>>
>> But out of pure curiosity back to the original question - is there a way
>> to
>> find out where a thread’s message queue is?
>>
>> Regards,
>> M
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>

if you wish you can do a small demo run a simple window app in windbg
and set this breakpoint

bp user32!DispatchMessageA “.if ( (poi(poi(esp+4)+4)) == 0xBABE ) {
!usermsg poi(esp+4) } .else {gc}”

( in this example i run iczelion tut 03 win.exe )

code a two liner to post a message to the app
int _tmain(int argc, _TCHAR* argv)
{
HWND WindowHandle;
WindowHandle = FindWindow(L"SimpleWinClass",L"Our First Window");
PostMessage(WindowHandle,0xBABE,0xB055,0xDEED);
return 0;
}

and run the post message app

windbg will break and spit this output

user32!DispatchMessageA:
7e4196b8 8bff mov edi,edi
0:000> bp user32!DispatchMessageA “.if ( (poi(poi(esp+4)+4)) == 0xBABE
) { !usermsg poi(esp+4) } .else {gc}”
breakpoint 0 redefined
0:000> g
hwnd:
Window 0016034c
Name Our First Window
Class SimpleWinClass
WndProc 00000000
Style WS_OVERLAPPED
ExStyle WS_EX_WINDOWEDGE WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR
HInstance 00400000
ParentWnd 00000000
Id 00000000
UserData 00000000
Unicode FALSE
ThreadId 000006c0
ProcessId 00000a14
Message: 0xBABE
wParam: b055
lParam: deed
Time: 12f999e
pt: (281, 175)
eax=0013ff60 ebx=7ffde000 ecx=0013ff60 edx=7c90e514 esi=0167f74c edi=0167f6ee
eip=7e4196b8 esp=0013ff54 ebp=0013ffac iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
user32!DispatchMessageA:
7e4196b8 8bff mov edi,edi

now let it idle

open a local kernel debugging session
and do

lkd> !process 0 2 win.exe
PROCESS 859478d8 SessionId: 0 Cid: 0a14 Peb: 7ffde000 ParentCid: 0a7c
DirBase: 0ff00460 ObjectTable: e1c16a68 HandleCount: 21.
Image: win.exe

THREAD 86d4a530 Cid 0a14.06c0 Teb: 7ffdd000 Win32Thread:
e1c81750 WAIT: (Executive) KernelMode Non-Alertable
SuspendCount 1
a8b597d4 SynchronizationEvent

grab the win32Thread value e1c81750

load the userkdx (beware this is old not valid for wxp and above and
iam explaining a debugging scenerion all bets off on production
scenerios do not assume anything this is just a demo)

and do

lkd> !dti e1c81750

*** Extension DLL(2167 Free) does not match target system(2600 Free)

et 0x86d4a530 t 0x??? q 0x??? i 0.86d4a714
PTHREADINFO @ 0xE1C81750
PtiLink.Flink @0x000007D8
ptl @0x00000000
ptlW32 @0x00000000
ppi @0x00000000
pq @0x00000000
spklActive @0x00000000
mlPost.pqmsgRead @0x00000000
mlPost.pqmsgWriteLast @0x00000000
mlPost.cMsgs 0xe1673318
spwndDefaultIme @0x00000119
spDefaultImc @0x000000AF
hklPrev 0xbbea6588
rpdesk @0xE3E37648
hdesk 0xe1673318
amdesk 0x00000000
pDeskInfo @0xE2B7F1F8
pClientInfo @0xBBE87EC0
TIF_flags TIF_ALLOWFOREGROUNDACTIVATE |
TIF_ALLOWOTHERACCOUNTHOOK | TIF_DELAYEDEVENT | TIF_DISABLEIME |
TIF_DONTATTACHQUEUE | TIF_DONTJOURNALATTACH | TIF_DOSEMULATOR |
TIF_GLOBALHOOKER | TIF_GUITHREADINITIALIZED | TIF_INACTIVATEAPPMSG |
TIF_MSGPOSCHANGED | TIF_SHUTDOWNCOMPLETE | TIF_SPINNING |
TIF_TRACKRECTVISIBLE | TIF_VDMAPP | TIF_WAITFORINPUTIDLE | TIF_WOW64 |
0x80000000
sphkCurrent @0x00000000
pEventQueueServer @0x00000000
hEventQueueClient 0x00000000
fsChangeBits QS_KEY
fsChangeBitsRemovd QS_ALLPOSTMESSAGE | QS_EVENT | QS_EXCLUSIVE |
QS_POSTMESSAGE | QS_SMSREPLY | QS_TIMER
fsWakeBits 0
fsWakeMask QS_MOUSEBUTTON
cPaintsReady 0x0000
cTimersReady 0x07d0
timeLast 0x00000000
ptLast.x 0xe11b80b4
ptLast.y 0x00000000
idLast 0x00000000
cQuit 0x00000000
exitCode 0x012f999e
pSBTrack 0x00000000
psmsSent @0x7FFDD6CC
psmsCurrent @0x01100000
fsHooks 0x00000000
aphkStart @0xE1C8183C l16
sphkCurrent @0x00000000
psmsReceiveList @0x00000000
ptdb @0x00000000
Thread @0x86D4A530
PriorityClass 124
cWindows 0x00000000
cVisWindows 0x000f01ff
pqAttach @0x00000000
iCursorLevel 0xe3f02f5c
pMenuState @0x00000000

now you can see it gives you a

mlPost.cMsgs 0xe1673318

you can check if our 0xBABE and 0xB055 or sitting there

lkd> dd /c 1 0xe1673318 l6
e1673318 00000000
e167331c 00000000
e1673320 0016034c
e1673324 0000babe
e1673328 0000b055
e167332c 0000deed

On 5/15/12, raj_r wrote:
> lkd> dt nt!_KTHREAD Win32Thread @@masm($thread)
> +0x130 Win32Thread : 0xe434add0 Void
> lkd> dt win32k!_W32THREAD 0xe434add0
> +0x000 pEThread : 0x85e7e350 _ETHREAD
> +0x004 RefCount : 1
> +0x008 ptlW32 : (null)
> +0x00c pgdiDcattr : (null)
> +0x010 pgdiBrushAttr : (null)
> +0x014 pUMPDObjs : (null)
> +0x018 pUMPDHeap : (null)
> +0x01c dwEngAcquireCount : 0
> +0x020 pSemTable : (null)
> +0x024 pUMPDObj : (null)
> lkd> ? @@masm($thread)
> Evaluate expression: -2048400560 = 85e7e350
>
> beyond 24 there are several undocumented fields which contains the
> message queue implementation details for example
> win32k!_getQueueStatus will play with +0x38
>
> there is an old userkdx.dll extension in windows2000 folder which can
> show some of these presently fields but that extension is valid only
> upt0 w2k and in > xp it can yield errenous results
>
> lkd> !dti e434add0
>
> *** Extension DLL(2167 Free) does not match target system(2600 Free)
>
> et 0x85e7e350 t 0x??? q 0x??? i 0.85e7e534
> PTHREADINFO @ 0xE434ADD0
> PtiLink.Flink @0x000000B0
> ptl @0x00000000
> ptlW32 @0x00000000
> ppi @0x00000000
> pq @0x00000000
> spklActive @0x00000000
> mlPost.pqmsgRead @0x00000000
> mlPost.pqmsgWriteLast @0x00000000
> mlPost.cMsgs 0x00000000
> spwndDefaultIme @0x00000000
> spDefaultImc @0x00000000
> hklPrev 0x00000000
> rpdesk @0xE4425760
> hdesk 0x00000000
> amdesk 0x00000000
> pDeskInfo @0xE2B7F1F8
> pClientInfo @0xBBE9CC28
> TIF_flags TIF_ALLOWFOREGROUNDACTIVATE |
> TIF_ALLOWOTHERACCOUNTHOOK | TIF_DELAYEDEVENT | TIF_DISABLEIME |
> TIF_DONTATTACHQUEUE | TIF_DONTJOURNALATTACH | TIF_DOSEMULATOR |
> TIF_GLOBALHOOKER | TIF_GUITHREADINITIALIZED | TIF_INACTIVATEAPPMSG |
> TIF_MSGPOSCHANGED | TIF_SHUTDOWNCOMPLETE | TIF_SPINNING |
> TIF_TRACKRECTVISIBLE | TIF_VDMAPP | TIF_WAITFORINPUTIDLE | TIF_WOW64 |
> 0x80000000
> sphkCurrent @0x00000000
> pEventQueueServer @0x00000000
> hEventQueueClient 0x00000000
> fsChangeBits QS_KEY
> fsChangeBitsRemovd 0
> fsWakeBits 0
> fsWakeMask QS_MOUSEBUTTON
> cPaintsReady 0x0000
> cTimersReady 0x0038
> timeLast 0x00000000
> ptLast.x 0xe148751c
> ptLast.y 0x00000000
> idLast 0x00000000
> cQuit 0x00000000
> exitCode 0x00000000
> pSBTrack 0x00000000
> psmsSent @0x7FFDC6CC
> psmsCurrent @0x01000020
> fsHooks 0xe437a008
> aphkStart @0xE434AEBC l16
> sphkCurrent @0x00000000
> psmsReceiveList @0x00000000
> ptdb @0x00000000
> Thread @0x85E7E350
> PriorityClass 0
> cWindows 0x00000000
> cVisWindows 0x000f01ff
> pqAttach @0x00000000
> iCursorLevel 0xe437a0b4
> pMenuState @0x00000000
>
>
> On 5/15/12, raj_r wrote:
>> again i am not sure if i understand you correct
>>
>> the threads message queues are system defined memory objects and are
>> created by the system if it deems that that there is a message queue
>> requirement
>>
>> not all threads are created with a message queue as such
>>
>> 1) i am not sure if you can query for a threads message queue address
>>
>> 2 ) also you cant find who posted the message to your threads message
>> queue
>>
>> all you can know is you have a message in your queue and you can
>> decide what to do with it because you got a MSG struct filled up with
>> details
>>
>> it is a dead letter drop box as they say in spy++ thrillers
>>
>> you run an infinte loop and sit waiting for system to hand you your
>> message
>>
>> system fills up the MSG struct when you call GetMessage() PeekMessage()
>> etc
>>
>> or you can use GetQueueStatus() etc to get a hint of the contents of
>> message queue
>>
>> also iirc there is a registry key which you can modify to increase the
>> size of message queue which has a default value of 10000 messages per
>> message queue
>>
>> if you are interested in internal implementation details then you can
>> try deciphering the
>>
>> XXX calls :slight_smile: in win32k.sys like xxxscansysqueue() xxxAllocQueue() etc
>>
>>
>> On 5/15/12, xxxxx@gmx.de wrote:
>>> Right! Thanks for the hint, I forgot about the simplest way - the
>>> message
>>> queue must be processed by a message loop once the thread is released.
>>> It
>>> definitely helped me to continue debugging the issue.
>>>
>>>
>>> But out of pure curiosity back to the original question - is there a way
>>> to
>>> find out where a thread’s message queue is?
>>>
>>> Regards,
>>> M
>>>
>>> —
>>> WINDBG is sponsored by OSR
>>>
>>> For our schedule of WDF, WDM, debugging and other seminars visit:
>>> http://www.osr.com/seminars
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http://www.osronline.com/page.cfm?name=ListServer
>>>
>>
>

> I’d like to monitor the content of an application’s main thread’s message

queue, but I have no idea how to get the address of it (WinDbg, kernel
debugging). Would anyone have a hint for me? The thing is, when our main
thread stays in WaitForSingleObject for a longer period of time, we get
sometimes “Not enough quota…” when calling PostMessage afterwards. It’s
clear to me it’s about the message queue being overflowed, but I cannot
find out (with Spy++) who posts so many messages to the main thread in the
meantime.
*****
The key to this is a very simple rule: never, ever, for any imaginable
reason, do a WaiFor in the main GUI thread. No discussions, no options,
no negotiation. An app with a WaitFor in the main GUI thread is simply a
defective piece of software and has to be rewritten to remove this defect.
Start from there as your basis.

You need to explain to whomever says this “must work without change” is
that it NEVER “worked”, and any illusion that it did was just that: an
illusion. You can’t turn crap into caviar no matter how hard you try.

Spy++ is how I would go after it. Presumably some part of this piece of
trash is posting messages to it, so all you need to do is watch the
messages. Unfortunately, Spy++ does not understand WM_APP and keeps
decoding unknown codes against WM_USER. Note that if the internal
messages use WM_USER, this is a serious design defect, and if they use
WM_APP it is at best marginal design. If PostMessage is used to post any
standard Windows message, the program design is defective and it must be
changed. If you are getting PostMessage queue overflow, you are already
in such deep trouble that there is almost no way to salvage the program,
unless you use I/O Completion Ports to handle the queueing.

See my essays on my MVP Tips site on message management and the use of IOCPs.

I’ve been writing Windows GUI apps since 1990, starting with Win16, and my
superficial reaction to your problem description is it is NOT, as you
referred to it, an “awful design”. It sounds like it would take
considerable improvement to have the design considered “awful”. It is far
worse than you can even imagine. I know, I’ve had to rewrite these
monsters. Good judgment is the result of experience. Experience is the
result of bad judgment. Let’s just say that my design sense is excellent,
and we’ll try to avoid discussing why that is, except to say I have a LOT
of experience in 20 years!

I suspect the current app is probably hopeless beyond recovery, and all
the chewing gum, baling wire, and duct tape you throw at it is not going
to save it. Better to go after the fundamental problems early than to add
kludge after kludge at each new manifestation of the underlying bad
design.
joe
*******

And no, I can’t change the awful design at the moment :slight_smile: I know the main
thread mustn’t be used for waiting long for an event, but as I said - I
can’t change it in the next months.

I’d like to find out what messages overflow the queue, and my second idea
(the first was Spy++) is to watch the main thread’s message queue.

Perhaps there are other good ideas?

Regards, Maciej


WINDBG is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

@raj r : Thanks for very detailed instructions! As I said - my question about how the message queue works was a bit off-topic, I am simply interested in it, it’s part of my job to deal with debugging daily. And I feel happy when digging in the dirt.

@Joseph : let’s say we programmers here suffer from the same thing Dilbert does… Thanks for your comments, they are correct and justified, the thing is even good arguments don’t work in the kind of matrix reality the management of big companies lives in. But it’s a different story. Now I am going back to keep on fighting against monsters!

Thanks once again,
Maciej