http://bugs.winehq.org/show_bug.cgi?id=13964
Summary: small .NET cmd util: CoWaitForMultipleHandles Unexpected wait termination Product: Wine Version: 1.0-rc5 Platform: PC-x86-64 URL: http://sourceforge.net/projects/outmodedbonsai/ OS/Version: Linux Status: UNCONFIRMED Severity: enhancement Priority: P2 Component: ole AssignedTo: wine-bugs@winehq.org ReportedBy: htl10@users.sourceforge.net
Created an attachment (id=14126) --> (http://bugs.winehq.org/attachment.cgi?id=14126) C# source code of the little program
I have a very small C# program which just reads a .NET assembly dll, then uses the .NET reflection API to query the dll's version, then write it out to the console. (it is just a .NET dll version checking tool, basically).
It works with mono on linux, and it works with win32 mono on wine; but with microsoft .NET Framework under wine, (i.e. running it "plain" rather than through win32 mono, if one has both mono and .net framework 2.0 installed), it dies with a few thousands of "err:ole:CoWaitForMultipleHandles Unexpected wait termination: -1, 87" among other messages which scrolls off screen. I have seens the CoWaitForMultipleHandles message under completely different contexts (http://bugs.winehq.org/show_bug.cgi?id=12259#c2)
This seems to be related to how the .Net Framework interacts with wine, since the executable in both mono linux and win32 mono +wine work as expected.
The source code of the small C# program is attached. I can provide a small executable if it helps - the small C# program is a stripped down version of BeanSprout in the sourceforge project (and I am the project admin, so I can upload it there).
I know some might say this is not worth the time since it works with mono/linux win32 mono/wine, but I have other .NET programs which works poorly with either, and works better with MS.Net but only occasionally dies with a similiar message with MS.Net... and the thousands of "err:ole:CoWaitForMultipleHandles" messages also seems to bug other people (bug 12259, and possibly others).
http://bugs.winehq.org/show_bug.cgi?id=13964
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #1 from Anastasius Focht focht@gmx.net 2008-06-17 01:46:45 --- Hello,
your WINEPREFIX is probably messed up. Make sure you use a clean .wine.
That c# sample works fine for me.
--- snip --- [focht@localhost work]$ wine ./testapp.exe "z:\home\focht\work\testapp.exe" fixme:virtual:NtAllocateVirtualMemory MEM_WRITE_WATCH type not supported fixme:shell:URL_ParseUrl failed to parse L"testapp" Found Genotyping Module version: 3.0.3090.13031 fixme:ole:CoGetContextToken stub fixme:ole:CoGetContextToken stub fixme:ole:CoGetContextToken stub fixme:ole:CoGetContextToken stub fixme:ole:CoGetContextToken stub --- snip ---
Regards
http://bugs.winehq.org/show_bug.cgi?id=13964
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |dotnet, download, source
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #2 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-17 20:14:29 --- (In reply to comment #1)
Hello,
your WINEPREFIX is probably messed up. Make sure you use a clean .wine.
That c# sample works fine for me.
--- snip --- [focht@localhost work]$ wine ./testapp.exe "z:\home\focht\work\testapp.exe"
<snipped>
You are correct, and the answer is also quite interesting. How did you decide to do the full path ("z:...\testapp.exe")?
I made a new clean WINEPREFIX in .wine2 with .NET 2, and I found that:
1) mono linux, win32 mono + wine accepts relative paths or files in current directory for the argument, .NET doesn't - it needs the full z:......
2) .NET2 throws an exception if a relative/current path is passed. The message is quite clear that a full path is required; however, in the old WINEPREFIX, the relevant exception message got swarmed and lost in a few thousands of "err:ole:CoWaitForMultipleHandles...". Unless you capture the whole thing, and know what to look for, you won't see it; in the new WINEPREFIX, the same exception is thrown, and as discussed elsewhere, WINE drops into a debug backtrace (which is much shorter) on receiving .NET exceptions, and so one gets 10 lines .NET error message and another 100 lines of wine back trace, which is much more readable.
So here are my thoughts: 1) I think my old WINEPREFIX is broken due to installation of some MS devel tools (I have .NET SDK, and the driver dev kit currently, and possibly tried VC express edition as well), I think some MS dev tool replaces wine's debug hooks? We probably want to fix that, or have an FAQ.
2) that said, my old WINEPREFIX is about 2GB in size, and have 15 applications in program menu, and 35 under the uninstaller menu (some of them are optional parts of the same big app) - I used about 1/2 of the applications in a "production" sense (i.e. using them and doing something useful from time to time). Of course I can do two WINEPREFIX, one for applications known to work well, and one for trying things out; but honestly I have only had this .wine (and this machine) for less than 3 months, and it is a bit painful to reinstall 2GB of software every 3 months.
Any tips/pointers for fixing wine's debug hooks?
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #3 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-18 00:32:34 --- It seems to be the NET SDK (which can be installed on its own, or come bundled with most recent Visual studio, and installed silently, I think).
Editing the [Software\Microsoft\Windows NT\CurrentVersion\AeDebug\] entry in system.reg and modify it from 'Debugger=vsjitdebugger.exe -p %ld -e %ld' to back to 'Debugger=winedbg --auto %ld %ld' restores the more agreeable behavior partly:
It now gives me the thousand lines of CoWaitForMultipleHandles, then the .NET exception message. Then the winedbg backtrace, instead of another thousand lines of CoWaitForMultipleHandles (the last bunch causes the .NET exception message to be lost in the middle of two groups of Cowait..).
So I need to find one more set of registry change to remove the jit debugger completely for the first set of CoWaitFor..., I think.
--- Comment #4 from Anastasius Focht focht@gmx.net 2008-06-18 09:12:31 --- Hello,
--- quote --- 1) mono linux, win32 mono + wine accepts relative paths or files in current directory for the argument, .NET doesn't - it needs the full z:...... --- quote ---
Well, mono's implementation of FileIOPermission(FileIOPermissionAccess access, string path) probably differs then. Talk about nonconformant behaviour.
--- quote --- Editing the [Software\Microsoft\Windows NT\CurrentVersion\AeDebug\] entry in system.reg and modify it from 'Debugger=vsjitdebugger.exe -p %ld -e %ld' to back to 'Debugger=winedbg --auto %ld %ld' restores the more agreeable behavior partly:
It now gives me the thousand lines of CoWaitForMultipleHandles, then the .NET exception message. Then the winedbg backtrace, instead of another thousand lines of CoWaitForMultipleHandles (the last bunch causes the .NET exception message to be lost in the middle of two groups of Cowait..).
So I need to find one more set of registry change to remove the jit debugger completely for the first set of CoWaitFor..., I think. --- quote ---
The registration of JIT Debugger into AeDebug is part of the .NET SDK/Visual Studio .NET setup. The .NET CLR doesn't look at AeDebug first when encountering unhandled exceptions to decide what to do...
HKEY_LOCAL_MACHINE\Software\Microsoft.NETFramework
DbgJITDebugLaunchSetting = 0x10 DbgManagedDebugger = "C:\windows\system32\vsjitdebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d"
If you want to fall back to default behaviour (avoiding CLR handler), you can set DbgJITDebugLaunchSetting = 0x0. This will invoke the crash handler from AeDebug key. The default managed debugger, which is specified by "DbgManagedDebugger" is spawned if DbgJITDebugLaunchSetting is set to 0x2 or 0x10.
--
Now for the real problem ... The managed CLR debugger (vsjitdebugger.exe) calls CoCreateInstance with CLSID {36BBB745-0999-4FD8-A538-4D4D84E4BD09} -> CLSID_JITDebuggingHost to connect to local debugging host. This spawns a local COM server (vsjitdebugger.exe with -embedding param).
Relevant code:
---- snip ---- /* FIXME: should call to rpcss instead */ HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { ... get_localserver_pipe_name(pipefn, rclsid);
while (tries++ < MAXTRIES) { TRACE("waiting for %s\n", debugstr_w(pipefn));
WaitNamedPipeW( pipefn, NMPWAIT_WAIT_FOREVER ); hPipe = CreateFileW(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (hPipe == INVALID_HANDLE_VALUE) { DWORD index; DWORD start_ticks; if (tries == 1) { if ( (hres = create_local_service(rclsid)) && (hres = create_server(rclsid)) ) return hres; } else { WARN("Connecting to %s, no response yet, retrying: le is %u\n", debugstr_w(pipefn), GetLastError()); } /* wait for one second, even if messages arrive */ start_ticks = GetTickCount(); do { CoWaitForMultipleHandles(0, 1000, 0, NULL, &index); } while (GetTickCount() - start_ticks < 1000); continue;
... } ---- snip ----
Actually the CoWaitForMultipleHandles(0, 1000, 0, NULL, &index) is wrong. CoWaitForMultipleHandles() calls MsgWaitForMultipleObjectsEx or WaitForMultipleObjectsEx depending if rpc/messages need to be pumped. They expect a least one (valid) handle to wait on. I bet such CoWaitForMultipleHandles() call fails on Windows too. Because of the quick failure and the surrounding loop, you get flooded with that messages.
The "FIXME" before RPC_GetLocalClassObject already indicates: this code needs some review/rework anyway.
Regards
--- Comment #5 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-18 20:03:15 --- Thanks for the analysis!
I also found something else - this MSDN article: http://msdn.microsoft.com/en-us/library/5hs4b7a6.aspx mentions two registry entries needed to be deleted to disable JIT debugging.
One of them is the registry entry I mentioned earlier, which removes the 2nd group of "CoWait..." ; removing the other entry mentioned, removes the first group of "CoWait...", but it gives a popup message instead saying no jit debugger instead and ask the user to confirm or cancel debugging. The MSDN article is incomplete then - I'll give modifying DbgJITDebugLaunchSetting a try.
Thanks a lot.
http://bugs.winehq.org/show_bug.cgi?id=13964
Hin-Tak Leung htl10@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #14126|0 |1 is obsolete| |
--- Comment #3 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-18 00:32:34 --- It seems to be the NET SDK (which can be installed on its own, or come bundled with most recent Visual studio, and installed silently, I think).
Editing the [Software\Microsoft\Windows NT\CurrentVersion\AeDebug\] entry in system.reg and modify it from 'Debugger=vsjitdebugger.exe -p %ld -e %ld' to back to 'Debugger=winedbg --auto %ld %ld' restores the more agreeable behavior partly:
It now gives me the thousand lines of CoWaitForMultipleHandles, then the .NET exception message. Then the winedbg backtrace, instead of another thousand lines of CoWaitForMultipleHandles (the last bunch causes the .NET exception message to be lost in the middle of two groups of Cowait..).
So I need to find one more set of registry change to remove the jit debugger completely for the first set of CoWaitFor..., I think.
--- Comment #4 from Anastasius Focht focht@gmx.net 2008-06-18 09:12:31 --- Hello,
--- quote --- 1) mono linux, win32 mono + wine accepts relative paths or files in current directory for the argument, .NET doesn't - it needs the full z:...... --- quote ---
Well, mono's implementation of FileIOPermission(FileIOPermissionAccess access, string path) probably differs then. Talk about nonconformant behaviour.
--- quote --- Editing the [Software\Microsoft\Windows NT\CurrentVersion\AeDebug\] entry in system.reg and modify it from 'Debugger=vsjitdebugger.exe -p %ld -e %ld' to back to 'Debugger=winedbg --auto %ld %ld' restores the more agreeable behavior partly:
It now gives me the thousand lines of CoWaitForMultipleHandles, then the .NET exception message. Then the winedbg backtrace, instead of another thousand lines of CoWaitForMultipleHandles (the last bunch causes the .NET exception message to be lost in the middle of two groups of Cowait..).
So I need to find one more set of registry change to remove the jit debugger completely for the first set of CoWaitFor..., I think. --- quote ---
The registration of JIT Debugger into AeDebug is part of the .NET SDK/Visual Studio .NET setup. The .NET CLR doesn't look at AeDebug first when encountering unhandled exceptions to decide what to do...
HKEY_LOCAL_MACHINE\Software\Microsoft.NETFramework
DbgJITDebugLaunchSetting = 0x10 DbgManagedDebugger = "C:\windows\system32\vsjitdebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d"
If you want to fall back to default behaviour (avoiding CLR handler), you can set DbgJITDebugLaunchSetting = 0x0. This will invoke the crash handler from AeDebug key. The default managed debugger, which is specified by "DbgManagedDebugger" is spawned if DbgJITDebugLaunchSetting is set to 0x2 or 0x10.
--
Now for the real problem ... The managed CLR debugger (vsjitdebugger.exe) calls CoCreateInstance with CLSID {36BBB745-0999-4FD8-A538-4D4D84E4BD09} -> CLSID_JITDebuggingHost to connect to local debugging host. This spawns a local COM server (vsjitdebugger.exe with -embedding param).
Relevant code:
---- snip ---- /* FIXME: should call to rpcss instead */ HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { ... get_localserver_pipe_name(pipefn, rclsid);
while (tries++ < MAXTRIES) { TRACE("waiting for %s\n", debugstr_w(pipefn));
WaitNamedPipeW( pipefn, NMPWAIT_WAIT_FOREVER ); hPipe = CreateFileW(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (hPipe == INVALID_HANDLE_VALUE) { DWORD index; DWORD start_ticks; if (tries == 1) { if ( (hres = create_local_service(rclsid)) && (hres = create_server(rclsid)) ) return hres; } else { WARN("Connecting to %s, no response yet, retrying: le is %u\n", debugstr_w(pipefn), GetLastError()); } /* wait for one second, even if messages arrive */ start_ticks = GetTickCount(); do { CoWaitForMultipleHandles(0, 1000, 0, NULL, &index); } while (GetTickCount() - start_ticks < 1000); continue;
... } ---- snip ----
Actually the CoWaitForMultipleHandles(0, 1000, 0, NULL, &index) is wrong. CoWaitForMultipleHandles() calls MsgWaitForMultipleObjectsEx or WaitForMultipleObjectsEx depending if rpc/messages need to be pumped. They expect a least one (valid) handle to wait on. I bet such CoWaitForMultipleHandles() call fails on Windows too. Because of the quick failure and the surrounding loop, you get flooded with that messages.
The "FIXME" before RPC_GetLocalClassObject already indicates: this code needs some review/rework anyway.
Regards
--- Comment #5 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-18 20:03:15 --- Thanks for the analysis!
I also found something else - this MSDN article: http://msdn.microsoft.com/en-us/library/5hs4b7a6.aspx mentions two registry entries needed to be deleted to disable JIT debugging.
One of them is the registry entry I mentioned earlier, which removes the 2nd group of "CoWait..." ; removing the other entry mentioned, removes the first group of "CoWait...", but it gives a popup message instead saying no jit debugger instead and ask the user to confirm or cancel debugging. The MSDN article is incomplete then - I'll give modifying DbgJITDebugLaunchSetting a try.
Thanks a lot.
--- Comment #6 from Hin-Tak Leung htl10@users.sourceforge.net 2008-06-20 18:16:10 --- Created an attachment (id=14223) --> (http://bugs.winehq.org/attachment.cgi?id=14223) a test binary, plus its source code.
This is the updated source code, and a test binary. The binary is the same as the binary of the same name inside http://sourceforge.net/project/showfiles.php?group_id=217165&package_id=...
The test binary does something very simple: it reads a .NET assembly and outputs its name and version. So you can run it against itself:
GTversionCheck.exe c:\path\GTversionCheck.exe
http://bugs.winehq.org/show_bug.cgi?id=13964
Rob Shearman robertshearman@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Component|ole |ole32
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #7 from Austin English austinenglish@gmail.com 2009-01-10 20:25:27 --- austin@austin-desktop:~$ wine GTversionCheck.exe "Z:\home\austin\GTversionCheck.exe" fixme:shell:URL_ParseUrl failed to parse L"GTversionCheck" Module GTversionCheck, Version=1.0.3091.7615, Culture=neutral, PublicKeyToken=null fixme:ole:CoGetContextToken stub
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #8 from Anastasius Focht focht@gmx.net 2009-01-11 01:43:44 --- Hello,
--- quote --- austin@austin-desktop:~$ wine GTversionCheck.exe "Z:\home\austin\GTversionCheck.exe" fixme:shell:URL_ParseUrl failed to parse L"GTversionCheck" Module GTversionCheck, Version=1.0.3091.7615, Culture=neutral, PublicKeyToken=null fixme:ole:CoGetContextToken stub --- quote ---
Your point? As already explained, there is nothing to fix here.
The interesting bits have already been discussed (hence bug 12259 references this bug). I suggest to close this one.
Regards
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #9 from Hin-Tak Leung htl10@users.sourceforge.net 2009-01-11 09:19:04 --- Hmm, I think wine should not allow MS dev tools to overwrite the debugger hooks in the registry? - since it doesn't work, and tend to mask other problems?
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #10 from Anastasius Focht focht@gmx.net 2009-01-11 10:08:48 --- Hello,
--- quote --- Hmm, I think wine should not allow MS dev tools to overwrite the debugger hooks in the registry? - since it doesn't work, and tend to mask other problems? --- quote ---
Sorry, but this is nonsense. AeDebug hook should be free for everyone. I also overwrite AeDebug hook with my own because there are cases where I don't want winedbg as default crash handler.
Regards
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #11 from Hin-Tak Leung htl10@users.sourceforge.net 2009-01-11 10:14:27 --- (In reply to comment #10)
Sorry, but this is nonsense. AeDebug hook should be free for everyone. I also overwrite AeDebug hook with my own because there are cases where I don't want winedbg as default crash handler.
okay, sorry... I guess we still need some kind of fix to avoid the flood of Cowait... messages though, since it masks real errors.
http://bugs.winehq.org/show_bug.cgi?id=13964
--- Comment #12 from Austin English austinenglish@gmail.com 2009-01-11 13:40:16 --- Fixed, per Anastasius.
http://bugs.winehq.org/show_bug.cgi?id=13964
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |FIXED
--- Comment #13 from Austin English austinenglish@gmail.com 2009-01-11 13:40:22 --- Fixed, per Anastasius.
http://bugs.winehq.org/show_bug.cgi?id=13964
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #14 from Alexandre Julliard julliard@winehq.org 2009-01-16 10:38:38 --- Closing bugs fixed in 1.1.13.
http://bugs.winehq.org/show_bug.cgi?id=13964
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |a803fa3578194a3ebee9a673c7d | |adf5180b48e67