Welcome to MSDN Blogs Sign in | Join | Help

Lock(object) and ThreadAbortException

We have experience some weird deadlock using managed code.

We have a class with some shared resources. To protect the shared resources, we create a synchronization object, and use Lock(object) prior to access the shared resources. There is no nested lock so in theory we should never have deadlock.

However, for some reason, one of the call has stucked in the Lock(object) call.

After a round of discussion with CLR team, we finally figure out the problem.

It is a debug build. (not surprising given we are in development.) The C# compiler generates the following code for Lock(object) in debug mode.

IL_0039: ldarg.0

IL_003a: ldfld stateLock

IL_003f: dup

IL_0040: stloc.3

IL_0041: call System.Threading.Monitor::Enter

IL_0046: nop

.try

{

...

} // end .try

.finally

{

  IL_005d: ldloc.3

  IL_005e: call System.Threading.Monitor::Exit

  IL_0063: nop

  IL_0064: endfinally

} // end .finally

You see, it inserts an extra nop between Monitor.Enter and try/finally. Right at the nop instruction, a ThreadAbortException is thrown in this thread, leaving the lock to be orphaned. (The exact reason why the exception is thrown is unknown. It is definitely not thrown by our code.)

Joe Duffy from CLR team has discussed the exact symptom in his blog

http://www.bluebytesoftware.com/blog/PermaLink,guid,d9ff204a-a8a5-400e-bcbc-dedb90a7d11a.aspx

Writing managed code does give you more challenge in writing reliable product.

Published Monday, July 30, 2007 8:00 AM by junfeng
Filed under:

Comments

# re: Lock(object) and ThreadAbortException

Monday, July 30, 2007 12:16 PM by Anderson Imes

I wouldn't say managed code makes it more challenging to write a reliable product - it just gives you a different set of reliability problems to worry about.

Reliability is always a challenge, no matter what language you work with.

# re: Lock(object) and ThreadAbortException

Tuesday, July 31, 2007 8:02 AM by Oleg Mihailik

Do you have a solution for that problem yet?

It appears to me that it must be a common major slip in 'using' and 'lock' statement implementation.

BTW, there is a way to amortise the trouble, by wrapping Monitor's functionality in CriticalFinalizer object. Even if async exception happens, the lock will be released sometimes latter.

But it is not the true solution in general case. I think Microsoft should address async exception problem with something substantial.

New Comments to this post are disabled
 
Page view tracker