There is a blurb with a general recommendation on choosing between those two waits reasons in the MSDN documentation for KeWaitForSingleObject (and similar kernel wait services), but there isn?t a hard and fast rule. Generally, UserRequest is intended to indicate a wait on behalf of some operation by user mode. There isn?t a behavioral difference presently built-in to the kernel between these two waits reasons, just what tools that can query the wait reason display (e.g. the debugger).
If you recursively take the lock and can?t easily move from a KMUTEX, then I would recommend setting Alertable to FALSE in most circumstances. This assumes that code running with the mutex held doesn?t perform long waits or other operations that could result in indefinitely holding up other code attempting to obtain synchronization on the lock. It is generally atypical to specify an alertable kernel mode wait unless you want to explicitly take action to break out of a long wait to allow thread termination to complete in a timely manner. If you make the wait non-alertable, then a thread termination request won?t interrupt the wait on the mutex object.
It is possible to catch these exceptions from KeReleaseMutex, but I would not recommend doing so in your situation. It is better to fix the code so that it keeps track of the ownership itself (otherwise you may perform an operation that you believe to be guarded by the lock, but which is not actually guarded by the lock when the code failed to obtain it in reality ? and that may result in more difficult to diagnose corruption).
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Aspiring Programmer
Sent: Monday, December 31, 2012 4:48 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Baffling KeReleaseMutex() and STATUS_MUTANT_NOT_OWNED Exceptions
Thank you. I’m trying to maintain an old driver written by someone else, and the challenge with switching to fast / guarded mutexes and spin locks across the board is that the code is highly recursive, and I’m pretty sure a lot of deadlocks will result.
I’m trying to understand what is happening, and have some more questions for you:
- In the call to KeWaitForMutexObject(), the driver currently specifies “Executive” as the “Wait reason” everywhere. Is there a reasonable way to determine the cases where specifying “UserRequest” is more appropriate?
Or should I just specify False for alertable, and that will take care of the alerting issue in all these cases?
- The DDK docs suggest that KeReleaseMutex() can raise STATUS_ABANDONED and STATUS_MUTEX_NOT_OWNED exceptions. Does this mean that I can use a try - catch block to trap these exceptions, and avert a blue screen?
From: Skywing >
To: Windows System Software Devs Interest List >
Sent: Monday, December 31, 2012 2:57 PM
Subject: RE: [ntdev] Baffling KeReleaseMutex() and STATUS_MUTANT_NOT_OWNED Exceptions
I should mention that the right choice of action here is likely to switch to a guarded mutex or fast mutex instead of a KMUTEX, provided that you need a schedulable synchronization mechanism. Otherwise, use a spin lock instead.
If you really must use a KMUTEX, you probably really want to use a nonalertable kernel mode wait here, so that you do not have the wait unexpectedly interrupted during process termination (you shouldn?t typically design the duration of mutex lock hold times to be long, so this is probably the right choice if you can?t switch to a guarded or fast mutex).
If you are allowing the mutex to become abandoned, don?t do that. Abandoned mutexes are typically only legitimately used to synchronize with user mode processes that might become terminated at any time, and even then, the actually valuable use cases are few and far between. Allowing a user mode program to synchronize your internal kernel mode data structures is a very bad idea, so you are (hopefully) not doing this.
- S (Msft)
________________________________
From: Skywingmailto:xxxxx
Sent: ?12/?31/?2012 14:29
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE: [ntdev] Baffling KeReleaseMutex() and STATUS_MUTANT_NOT_OWNED Exceptions
Yes, you need to check the return value of KeWaitForMutexObject in the wait configuration that you supplied, unless you are guaranteed to only execute this code on a system thread and never permit the mutex to become abandoned. (And not checking the return value in that situation is bad practice as it results in the code only working due to subtle and easily overlooked circumstances.)
Consider the case where this code is running on a user mode thread, and thread termination is requested for this thread while your code is waiting in KeWaitForMutexObject(). Because you have declared the wait to be kernel mode alertable, the routine will return with STATUS_ALERTED, but without granting ownership of the mutex. Only STATUS_SUCCESS (or STATUS_WAIT_0 + n, in the case of a wait multiple service request where ?n? is the index of the signaled object), or STATUS_ABANDONED_WAIT_0 (+ n in the case of a wait multiple service request) indicate that mutex ownership has been granted.
Subsequently, your logic may attempt to then release the mutex without having ever gained ownership of it, which is illegal.
- S (Msft)
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of Aspiring Programmer
Sent: Monday, December 31, 2012 1:56 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Baffling KeReleaseMutex() and STATUS_MUTANT_NOT_OWNED Exceptions
I’m sporadically getting these inexplicable blue screens on calling the KeReleaseMutex() API.
EXCEPTION_CODE: (NTSTATUS) 0xc0000046 - An attempt to release a mutant object was made by a thread that was not the owner of the mutant object.
The code looks like this:
KeWaitForMutexObject(
&sendingState->mutexForSendingState,
Executive,
KernelMode,
TRUE,
NULL);
if(sendingState->SendingCancelled == TRUE)
{
KeReleaseMutex(&sendingState->mutexForSendingState, FALSE);
return;
}
It works well almost all the time, but on occasion I get the above blue screen.
Should I be checking the return value of KeWaitForMutexObject() and call KeReleaseMutex() only in case of success?
From the documentation it looks like all possible return values of KeWaitForMutexObject() are NT_SUCCESS, so what am I doing wrong here?
Should I be using a try - catch block to trap the exception, in order to prevent the blue screeen?
—
NTDEV 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
—
NTDEV 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
—
NTDEV 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
—
NTDEV 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</mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>