[Mono-bugs] [Bug 651546] New: Monitor.Enter leaves orphaned locks when threads are aborted

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Thu Nov 4 18:56:56 EDT 2010



           Summary: Monitor.Enter leaves orphaned locks when threads are
    Classification: Mono
           Product: Mono: Runtime
           Version: 2.8.x
          Platform: x86-64
        OS/Version: openSUSE 11.2
            Status: NEW
          Severity: Major
          Priority: P5 - None
         Component: io-layer
        AssignedTo: lupus at novell.com
        ReportedBy: rkvinge at novell.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---
           Blocker: ---

Created an attachment (id=398700)
 --> (http://bugzilla.novell.com/attachment.cgi?id=398700)
test case

Compile and run the attached test case, I see this output 49/50 times:

Starting thread 0
Thread 0 entered 1
Thread 0 locked
Starting thread 1
Thread 1 entered 2
Starting thread 2
Thread 2 entered 3
Done starting threads, waiting a bit
Done waiting for appdomain, unloading it
Thread 0 unlocked
Thread 0 excepted: Thread was being aborted unlocked: True
Thread 0 exited
Thread 1 excepted: Thread was being aborted unlocked: False
Thread 1 left an orphaned lock! Test failed!
Thread 1 exited

[and program does not exit]

I'm on a "Intel(R) Core(TM)2 CPU T7200 @ 2.00GHz" according to cpuinfo, with
x86-64 OS 11.2.

I've been debugging a bit, and the following happens:
* thread 0 has acquired the lock, thread 1 and 2 are waiting for the lock
* a domain unload is requested
* a thread abort exception is thrown in thread 0, effectively releasing the
* thread 1 acquires the lock, and when the generic monitor enter trampoline is
about to finish, it checks for pending exceptions, and the thread abort
exception is thrown. this exception will not reach the finally clause which
releases the lock, effectively leaving an orphaned lock
* thread 2 continues waiting for the lock thread 1 still has, but which will
never release, since thread 1 doesn't exist anymore.

it all boils down to this:

Monitor.Enter (obj);
try {

MS has special cased this so that when the lock has been acquired, they're
inside the try clause [1]. The difference is that in their scenario the issue
would only happen if the TAE is throw after the lock has been aqcuired, but
before entering the try block (a really tiny window), in our scenario it
happens if the TAE is thrown at any time after entering Monitor.Enter (a really
huge window).

One way to at least make this window smaller for us would possibly be to check
for pending TAEs after successfully acquiring the lock, and then just release
the lock before continuing.


Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.

More information about the mono-bugs mailing list