Hi,
I have an application that is hitting the assert in HOOK_CallHooks.
------ trace:hook:HOOK_CallHooks calling hook in thread 0113 WH_CALLWNDPROC code 0 wp 0 lp 7fbef984 err:hook:HOOK_CallHooks Unknown hook id 4 wine-pthread: hook.c:381: HOOK_CallHooks: Assertion `0' failed. ------
Basically I have a call stack that looks like this:
4 0x7f886b31 HOOK_CallHooks+0x251(id=0x4, code=0x0, wparam=0x0, lparam=0x7fbef984, unicode=0x0) [dlls/user/hook.c:381] in user32 (0x7fbef944)
5 0x7f8a4e8c call_window_proc+0x9c(hwnd=0x0, msg=0x0, wparam=0x0, lparam=0x0, unicode=0x0, same_thread=0x0) [dlls/user/message.c:1512] in user32 (0x7fbef9a0)
6 0x7f8a5dca peek_message(msg=0x7fbefcd0, hwnd=0x0, first=0x0, last=0xffffffff, flags=0x1) [dlls/user/message.c:2053] in user32 (0x7fbefca8)
7 0x7f8a7a16 PeekMessageW(msg_out=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0, flags=0x1) [dlls/user/message.c:2694] in user32 (0x7fbefcfc)
8 0x7f8a7cc9 GetMessageW+0x109(msg=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0) [dlls/user/message.c:2764] in user32 (0x7fbefdb0)
9 0x7f8a7e67 GetMessageA+0x37(msg=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0) [dlls/user/message.c:2804] in user32 (0x7fbefdd0)
-------------------
The WH_CALLWNDPROC is usually filtered out by the HOOK_IsHooked() call, but not in this case. I don't have source code available for the application. I was hoping somebody might have a good suggestion for the next step in debugging this problem. Right now I am going to start looking at GetMessageA and follow that code down to call_window_proc and see if I see something obvious.
Thanks, Phil
Unfortunately this problem I am seeing is very hard to reproduce. I have added some more debug in case it happens again. However, looking at code, the HOOK_IsHooked function seems strange:
BOOL HOOK_IsHooked( INT id ) { struct user_thread_info *thread_info = get_user_thread_info();
if (!thread_info->active_hooks) return TRUE; return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0; }
Active_hooks is pretty much set by the server. Bit 0x80000000 is set to indicate that the bitmask is valid. One of my suspicions that I hope to confirm with debug is that in my case of failure active_hooks is 0.
Would it not make more sense to return FALSE from this routine in that case? That is to say, if the bitmask is NOT valid, miss processing the hook instead of erroneously trying to process a hook that is not set.
Even if that is the case, I will have to figure out the real problem of why active_hooks is 0.
Thanks, Phil
-----Original Message----- From: wine-devel-bounces@winehq.org [mailto:wine-devel-bounces@winehq.org] On Behalf Of Phil Lodwick Sent: Friday, November 03, 2006 4:25 PM To: wine-devel@winehq.org Subject: dlls/user/hook.c HOOK_CallHooks() help
Hi,
I have an application that is hitting the assert in HOOK_CallHooks.
------ trace:hook:HOOK_CallHooks calling hook in thread 0113 WH_CALLWNDPROC code 0 wp 0 lp 7fbef984 err:hook:HOOK_CallHooks Unknown hook id 4 wine-pthread: hook.c:381: HOOK_CallHooks: Assertion `0' failed. ------
Basically I have a call stack that looks like this:
4 0x7f886b31 HOOK_CallHooks+0x251(id=0x4, code=0x0, wparam=0x0, lparam=0x7fbef984, unicode=0x0) [dlls/user/hook.c:381] in user32 (0x7fbef944)
5 0x7f8a4e8c call_window_proc+0x9c(hwnd=0x0, msg=0x0, wparam=0x0, lparam=0x0, unicode=0x0, same_thread=0x0) [dlls/user/message.c:1512] in user32 (0x7fbef9a0)
6 0x7f8a5dca peek_message(msg=0x7fbefcd0, hwnd=0x0, first=0x0, last=0xffffffff, flags=0x1) [dlls/user/message.c:2053] in user32 (0x7fbefca8)
7 0x7f8a7a16 PeekMessageW(msg_out=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0, flags=0x1) [dlls/user/message.c:2694] in user32 (0x7fbefcfc)
8 0x7f8a7cc9 GetMessageW+0x109(msg=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0) [dlls/user/message.c:2764] in user32 (0x7fbefdb0)
9 0x7f8a7e67 GetMessageA+0x37(msg=0x7fbefe10, hwnd=0x0, first=0x0, last=0x0) [dlls/user/message.c:2804] in user32 (0x7fbefdd0)
-------------------
The WH_CALLWNDPROC is usually filtered out by the HOOK_IsHooked() call, but not in this case. I don't have source code available for the application. I was hoping somebody might have a good suggestion for the next step in debugging this problem. Right now I am going to start looking at GetMessageA and follow that code down to call_window_proc and see if I see something obvious.
Thanks, Phil
"Phil Lodwick" Phil.Lodwick@EFI.COM writes:
Active_hooks is pretty much set by the server. Bit 0x80000000 is set to indicate that the bitmask is valid. One of my suspicions that I hope to confirm with debug is that in my case of failure active_hooks is 0.
Would it not make more sense to return FALSE from this routine in that case? That is to say, if the bitmask is NOT valid, miss processing the hook instead of erroneously trying to process a hook that is not set.
The idea is that active_hooks is a shortcut to avoid calling the server if we know that a hook is not set. If we don't have a valid active_hooks then we need to call the server, which will then tell us whether or not we really have a hook to call.
Alexandre,
The idea is that active_hooks is a shortcut to avoid calling the server if we know that a hook is not set. If we don't have a valid active_hooks then we need to call the server, which will then tell us whether or not we really have a hook to call.
I don't know if this matters, but when I add more debug (+hook,+msg) I don't see the problem. Could be a coincidence. Anyway, I have added some debug information and my theory that thread_info->active_hooks being 0 is true. With your explanation of the code I think I have a pretty good understanding of what is supposed to happen -- but something is strange. It appears that even after a trip to the server thread_info->active_hooks is 0. I have stared at code but I don't see how this can be the case.
HOOK_CallHooks() we have code that looks like:
// Understanding Alexandre's explanation, it is very valid to skip past // this call if we still need to get active_hooks from the server. if (!HOOK_IsHooked( id )) return;
tid = 0; MyDebugOriginalActiveHooks = thread_info->active_hooks;
SERVER_START_REQ( start_hook_chain ) { if (!wine_server_call( req )) { tid = reply->tid; thread_info->active_hooks = reply->active_hooks; } }
if (tid) { switch(id) { default: ERR("Unknown hook id %d\n", id); FIXME("Original Hooks = %x; CurrentHooks = %x", MyDebugOriginalActiveHooks, thread_info->active_hooks); assert(0); } }
We hit the assert and the active_hooks are 0 before and after the call to the server. Since tid is non-zero it means we hit the server successfully. I must be missing something really basic.
Phil
I am beginning to suspect a problem with wine_server_call. I am confused because I would have thought this was something that is pretty solid.
In HOOK_CallHooks we call SERVER_START_REQ( start_hook_chain ). When I put debugging in the server I see that reply->active_hooks is getting properly set to 0x8000000. We return from this function at the /* no hook set */ comment and I see that reply->active_hooks is still 0x80000000.
However, when we return the client believes reply->active_hooks is 0. Could it be possible that read_reply_data in ntdll/server.c is failing?
Any insight would be greatly appreciated.
Thanks, Phil