Hi,
According to MSDN http://msdn.microsoft.com/en-us/library/ms682608(VS.85).aspx:
EnterCriticalSection can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout.
Currently, WIne doesn't implement this timeout feature, instead wine throws exception only for Wine internal locks after waiting for about 65 seconds, it is useful to check deadlock, see RtlpWaitForCriticalSection in dlls/ntdll/critsection.c
But this means a thread can't hold critical section longer than 65 seconds, otherwise app will crash. On some conditions, a thread does need hold critical section more than 65 seconds, for example: wine's implementation of GetAddress uses a critical section to protect non-reentrant gethostbyname() (well maybe need another gethostbyname_r() patch), see dlls/wininet/utility.c As you can see, gethostbyname() may take longtime when DNS setting is wrong or network is broken. If a multi-thread app calls GetAddress simultaneous in many threads, the app will crash.
I meet this problem when my network was broken, my app kept crash:
fixme:wininet:InternetSetOptionW INTERNET_OPTION_SEND/RECEIVE_TIMEOUT err:ntdll:RtlpWaitForCriticalSection section 0x7e44fa80 "utility.c: cs_gethostbyname" wait timed out in thread 0037, blocked by 003b, retrying (60 sec) fixme:msxml:DllCanUnloadNow wine: Critical section 7e44fa80 wait failed at address 0x7bc3c5bc (thread 0039), starting debugger... WineDbg starting on pid 0008 Unhandled exception: wait failed on critical section 0x7e44fa80 cs_gethostbyname err:seh:raise_exception Unhandled exception code c0000194 flags 0 addr 0x7bc3c5bc
So I suggest a feature that EnterCriticalSection throws exception for Wine internal locks only when debug is present.
Add the following code dlls/ntdll/critsection.c:
NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) { ........................... /* Throw exception only for Wine internal locks and debug is present */ if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[0])) continue; else if (!NtCurrentTeb()->Peb->BeingDebugged) continue; ^^^^^^^^^^^^^^^^^^ add ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
rec.ExceptionCode = STATUS_POSSIBLE_DEADLOCK; ............................ }
Any suggestion? Sorry If I'm not clean or missing something, thanks.
2008/7/2 Huang, Zhangrong hzhrong@gmail.com: ...
On some conditions, a thread does need hold critical section more than 65 seconds, for example: wine's implementation of GetAddress uses a critical section to protect non-reentrant gethostbyname() (well maybe need another gethostbyname_r() patch), see dlls/wininet/utility.c As you can see, gethostbyname() may take longtime when DNS setting is wrong or network is broken. If a multi-thread app calls GetAddress simultaneous in many threads, the app will crash.
A bit of lateral thinking is needed, I feel, since contention between threads is going to be an issue even if the lock doesn't time out. The wininet code should be converted to using getaddrinfo and as a bonus it will also start supporting IPv6 hosts.
Hi,
2008/7/3 Rob Shearman robertshearman@gmail.com:
A bit of lateral thinking is needed, I feel, since contention between threads is going to be an issue even if the lock doesn't time out. The wininet code should be converted to using getaddrinfo and as a bonus it will also start supporting IPv6 hosts.
I see.
So I suggest a feature that EnterCriticalSection throws exception for Wine internal locks only when debug is present.
Can we accept this feature: throw exception only when debug is present? Thanks.
Hello,
2008/7/2 Huang, Zhangrong hzhrong@gmail.com:
Hi,
2008/7/3 Rob Shearman robertshearman@gmail.com:
A bit of lateral thinking is needed, I feel, since contention between threads is going to be an issue even if the lock doesn't time out. The wininet code should be converted to using getaddrinfo and as a bonus it will also start supporting IPv6 hosts.
I see.
So I suggest a feature that EnterCriticalSection throws exception for Wine internal locks only when debug is present.
Can we accept this feature: throw exception only when debug is present?
I think that is a bad idea, while there might be 1 or 2 real genuine uses for only throwing an exception while debugging, 99% of the time it's really wine deadlocking itself, it's wine's own fault and I would rather see the backtraces of the deadlock rather then the app hanging forever.
Critical sections are meant for short time locks, if you keep a critical section for more then 1 minute there is something seriously wrong.
Cheers, Maarten.
Is there a way within wine or wine debug to tell it to output just the API's which are being called? I am trying to debug a exception that causes an application to crash. As usual I don't have the windows source code in order to debug it that way.
So I was hoping there is a way within wine to tell what API's are being called.
Sincerely Chris
On Wed, Jul 2, 2008 at 10:29 PM, Chris Ahrendt celticht32@aol.com wrote:
Is there a way within wine or wine debug to tell it to output just the API's which are being called? I am trying to debug a exception that causes an application to crash. As usual I don't have the windows source code in order to debug it that way.
So I was hoping there is a way within wine to tell what API's are being called.
http://wiki.winehq.org/DebugChannels
Highly recommended to guess which channels you need as opposed to turning them all on. The logs balloon quickly.
--John Klehm
On Wed, Jul 2, 2008 at 10:29 PM, Chris Ahrendt celticht32@aol.com wrote:
Is there a way within wine or wine debug to tell it to output just the API's which are being called? I am trying to debug a exception that causes an application to crash. As usual I don't have the windows source code in order to debug it that way.
So I was hoping there is a way within wine to tell what API's are being called.
Sincerely Chris
WINEDEBUG=+relay
Austin English wrote:
On Wed, Jul 2, 2008 at 10:29 PM, Chris Ahrendt celticht32@aol.com wrote:
Is there a way within wine or wine debug to tell it to output just the API's which are being called? I am trying to debug a exception that causes an application to crash. As usual I don't have the windows source code in order to debug it that way.
So I was hoping there is a way within wine to tell what API's are being called.
Sincerely Chris
WINEDEBUG=+relay
Not looking for the calls within wine... thanks for all the pointers guys.. esp the one to all the flags..
What I am looking for exactly is a way to just get wine to dump the Win32 API calls that are made... I am trying to figure out what an application calls right before it gets an exception from the result sent back from wine. If I knew the API its calling I could write a test case and find the issue.
So is there any way to output just the win32 API calls and no wine information.
Chris
So is there any way to output just the win32 API calls and no wine information.
That's precisely what +relay does. I'm not sure what you mean by "no wine information." --Juan
Juan Lang wrote:
So is there any way to output just the win32 API calls and no wine information.
That's precisely what +relay does. I'm not sure what you mean by "no wine information." --Juan
Ok when I put +relay on I get alot of other stuff I am not looking for...
So what I am looking for is application A called Win32 api say an open window or other such thing... I cant remember the exact api's (G) its been a long week at work..
So it would be like this
trace:d3d_caps:<win32 API called> returning w:1600, h:1200, ref:60, fmt:WINED3DFMT_X8R8G8B8
or something along those lines...
if relay does that does it also put in the wine calls as well? if it does is there any way to filter those out... I just want the high level API calls nothing more...
chris
Sorry if this is rambling... like I said its been a LONG Week....
Ok when I put +relay on I get alot of other stuff I am not looking for...
Sure. Some Windows APIs call other Windows APIs. +relay almost always produces too much information, but guessing which debug channel you really want is hard. Sometimes you have to read the relay channel to guess which channel you really want.
So it would be like this
trace:d3d_caps:<win32 API called> returning w:1600, h:1200, ref:60, fmt:WINED3DFMT_X8R8G8B8
No, that'll only appear if you turn on trace for the d3d_caps channel. +relay only turns it on for the relay channel. --Juan
Juan Lang wrote:
Ok when I put +relay on I get alot of other stuff I am not looking for...
Sure. Some Windows APIs call other Windows APIs. +relay almost always produces too much information, but guessing which debug channel you really want is hard. Sometimes you have to read the relay channel to guess which channel you really want.
So it would be like this
trace:d3d_caps:<win32 API called> returning w:1600, h:1200, ref:60, fmt:WINED3DFMT_X8R8G8B8
No, that'll only appear if you turn on trace for the d3d_caps channel. +relay only turns it on for the relay channel. --Juan
ok so its wade through relay time I guess... =) and then take a wild guess... sigh...
chris
Hi,
2008/7/3 Maarten Lankhorst m.b.lankhorst@gmail.com:
Hello, I think that is a bad idea, while there might be 1 or 2 real genuine uses for only throwing an exception while debugging, 99% of the time it's really wine deadlocking itself, it's wine's own fault and I would rather see the backtraces of the deadlock rather then the app hanging forever.
OK, my thoughts:
1. A patch for Wine that throws exception for Wine internal locks only when debug is present, so after waiting for 65 seconds, some apps don't crash. Of course if you run app under debugger, you get exception to check deadlock.
2. Another patch to implement the missing timeout feature, Wine checks the timeout value NtCurrentTeb()->Peb->CriticalSectionTimeout which comes from registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout, then throws EXCEPTION_POSSIBLE_DEADLOCK.. So if you want to check deadlock, setting the registry value to 30 seconds or 60 seconds or any value you want.
Huang, Zhangrong wrote:
Hi,
2008/7/3 Maarten Lankhorst m.b.lankhorst@gmail.com:
Hello, I think that is a bad idea, while there might be 1 or 2 real genuine uses for only throwing an exception while debugging, 99% of the time it's really wine deadlocking itself, it's wine's own fault and I would rather see the backtraces of the deadlock rather then the app hanging forever.
OK, my thoughts:
- A patch for Wine that throws exception for Wine internal locks only
when debug is present, so after waiting for 65 seconds, some apps don't crash. Of course if you run app under debugger, you get exception to check deadlock.
- Another patch to implement the missing timeout feature, Wine checks
the timeout value NtCurrentTeb()->Peb->CriticalSectionTimeout which comes from registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout, then throws EXCEPTION_POSSIBLE_DEADLOCK.. So if you want to check deadlock, setting the registry value to 30 seconds or 60 seconds or any value you want.
Using something like this in Wine currently is ill advised. For example crit-sections in sound drivers will timeout when some games load next level on a slow hardware. However everything is functioning properly after game is loaded. Generating an exception will most likely cause app to crash/exit.
This can be the case for number of other resources protected with crit-sections.
Vitaliy.
Huang, Zhangrong wrote:
Hi,
2008/7/3 Maarten Lankhorst m.b.lankhorst@gmail.com:
Hello, I think that is a bad idea, while there might be 1 or 2 real genuine uses for only throwing an exception while debugging, 99% of the time it's really wine deadlocking itself, it's wine's own fault and I would rather see the backtraces of the deadlock rather then the app hanging forever.
OK, my thoughts:
- A patch for Wine that throws exception for Wine internal locks only
when debug is present, so after waiting for 65 seconds, some apps don't crash. Of course if you run app under debugger, you get exception to check deadlock.
- Another patch to implement the missing timeout feature, Wine checks
the timeout value NtCurrentTeb()->Peb->CriticalSectionTimeout which comes from registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout, then throws EXCEPTION_POSSIBLE_DEADLOCK.. So if you want to check deadlock, setting the registry value to 30 seconds or 60 seconds or any value you want.
I personally prefer setting a flag of some sort. Also have someway of preventing wine from locking.. So option 2 looks better to me than option one.. option one can cause some confusion. Also have the time out added to the winecfg and have it manage the registry.
While we are at it =D Since I read that its possible to set the wine debug flags in the registry (I don't remember where I read it on winehq) why not have a tab in winecfg (or in the pannels that the gentleman is working on for the summer of code) which lets you have check boxes with all the flags on it to set the registry. Divide it up even into these are wine internal flags.. these are win flags etc... still provide for the WINEDEBUG=+relay etc facility..
Second thought : Where would I put in a feature request to tell the various trace channels to send to a log file or pipe instead of having to manually pipe it... that way others could write tools that listen on the pipe to write debuging utilities....
Just my 2cp
Chris