Bug 317196 (MONO72637) - [RACE?] DeleteCriticalSection assertion failed error
Summary: [RACE?] DeleteCriticalSection assertion failed error
Status: RESOLVED FIXED
Alias: MONO72637
Product: Mono: Runtime
Classification: Mono
Component: misc (show other bugs)
Version: unspecified
Hardware: Other Linux
: P3 - Medium : Enhancement
Target Milestone: ---
Assignee: Mono Bugs
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-16 14:01 UTC by Vadim Guzev
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
Test that reproduce error with Glib-CRITICAL **: ghash.c (857 bytes, text/plain)
2005-02-24 17:00 UTC, Thomas Wiest
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 19:07:25 UTC


---- Reported by vguzev@yandex.ru 2005-02-16 07:01:56 MST ----

Hi!


Does anyone know what does this error mean?
--8<------------------------------------------
** ERROR **: file critical-sections.c: line 89 (DeleteCriticalSection): 
assertion failed: (ret == 0)
aborting...
Aborted
--8<------------------------------------------

I think that it's thrown when I call Environment.Exit() - my application 
where I get this error uses a lot of threads and quite complex, so 
unfortunately I can't provide a small sample that can reproduce this 
error. It appears just before the application finish it's execution, but 
not always (approximately once per 20 launches).

I see that there's only one place where it could be in 
DeleteCriticalSection:
--8<--mono/io-layer/critical-sections.c-------
ret = mono_mutex_destroy(&section->mutex);
g_assert (ret == 0);
--8<------------------------------------------

In this function:
--8<--mono/io-layer/mono-mutex.c--------------
int
mono_mutex_destroy (mono_mutex_t *mutex)
{
        int ret = 0;
        int thr_ret;

        switch (mutex->type) {
        case MONO_MUTEX_NORMAL:
                ret = pthread_mutex_destroy (&mutex->mutex);
                break;
        case MONO_MUTEX_RECURSIVE:
                if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
                        thr_ret = pthread_cond_destroy (&mutex->cond);
                        g_assert (thr_ret == 0);
                }
        }

        return ret;
}
--8<------------------------------------------

It seems that the mutex passed as parameters is NULL!

Here's what is written in pthread.c (this can be different if you use 
other version of pthread)
--8<---pthread.c------------------------------
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
    if (mutex == NULL)
        return pth_error(EINVAL, EINVAL);
    free(*mutex);
    *mutex = NULL;
    return OK;
}
--8<------------------------------------------

So, the only one place where this function can return value != 0 is when 
mutex == NULL.
And here's what "man" says about pthread functions:

--8<--man-------------------------------------
RETURN VALUE
pthread_mutex_init always returns 0. The other mutex functions return 0
on success and a non-zero error code on error.
--8<------------------------------------------

Can we add some checkings for (mutex != null) to get rid of this annoying 
message?

Additional info:
--8<-----------------------------------------
[vadim@skif io-layer]$ uname -a
Linux skif 2.4.25 #2 SMP Fri Apr 23 14:03:00 MSD 2004 i686 athlon i386 
GNU/Linux
[vadim@skif io-layer]$ mono --version
Mono JIT compiler version 1.0.5, (C) 2002-2004 Novell, Inc and 
Contributors. www.go-mono.com
        TLS:           __thread
        GC:            Included Boehm (with typed GC)
        SIGSEGV      : normal
        Globalization: ICU
--8<-----------------------------------------


Best regards,
Vadim B. Guzev
http://u.pereslavl.ru/~vadim/MCSharp/



---- Additional Comments From vargaz@gmail.com 2005-02-16 09:41:47 MST ----

This is most likely due to a race condition in the code handling 
Environment.Exit. We are suspending all managed threads before shutting
down, but don't wait for them to actually become suspended, so they
continue running, trying to access runtime structures which are already
freed.



---- Additional Comments From vguzev@yandex.ru 2005-02-16 10:15:20 MST ----

I think this can be a source of a lot of mistakes. For example in 
this sample two threads are trying to free mutex and I think there 
will be more errors if we'll use a lot of threads simultaneously.
Can this be fixed in version 1.1.4?





---- Additional Comments From bmaurer@users.sf.net 2005-02-16 10:33:13 MST ----

If you do have a sample (no matter how large) that consistantly 
reproduces inconsistantly, that would be helpful.

1.1.4 is already rolled, so it is unlikely anything will get changed 
there. It would help if you could try out your program on HEAD or 
1.1.4.



---- Additional Comments From dick@ximian.com 2005-02-16 13:07:54 MST ----

The assert in critical-sections.c is showing that someone has a
mismatch between EnterCriticalSection and LeaveCriticalSection





---- Additional Comments From vguzev@yandex.ru 2005-02-24 09:58:36 MST ----

OK, Here's another one sample (attached).
It starts 1000 threads, that're trying to call 
System.Environment.Exit at a given time (in the nearest 10 seconds).

When I try to run it on Mono 1.1.4 I get the following errors:
--8<-------------------------------------------
[vadim@skif testsimultaneousexit]$ mono test.exe
Current date: 02/24/2005 16:44:45
Stopping after: 02/24/2005 16:44:50
Stopped..
Stopped..

(test.exe:24250): GLib-CRITICAL **: file ghash.c: line 225 
(g_hash_table_lookup): assertion `hash_table != NULL' failed

(test.exe:24250): GLib-CRITICAL **: file ghash.c: line 225 
(g_hash_table_lookup): assertion `hash_table != NULL' failed

(test.exe:24250): GLib-CRITICAL **: file ghash.c: line 225 
(g_hash_table_lookup): assertion `hash_table != NULL' failed

(test.exe:24250): GLib-CRITICAL **: file ghash.c: line 225 
(g_hash_table_lookup): assertion `hash_table != NULL' failed

** ERROR **: file mempool.c: line 144 (mono_mempool_alloc): 
assertion failed: (pool != NULL)
aborting...
Aborted
--8<-------------------------------------------

Sometimes it works as expected.
What's interesting, that if I try remove line 'Console.WriteLine
( "Stopped.." );' then the program just hangs on without any errors 
and doesn't exit at all...


Best regards,
Vadim B. Guzev
http://u.pereslavl.ru/~vadim/MCSharp/




---- Additional Comments From vguzev@yandex.ru 2005-02-24 10:00:06 MST ----

Created an attachment (id=167411)
Test that reproduce error with Glib-CRITICAL **: ghash.c




---- Additional Comments From vguzev@yandex.ru 2005-02-24 10:44:18 MST ----

Small test sample that reproduces the error with critical-sections.h 
can be found here:

https://bugzilla.novell.com/show_bug.cgi?id=MONO72970


Best regards,
Vadim B. Guzev
http://u.pereslavl.ru/~vadim/MCSharp/



---- Additional Comments From gonzalo@ximian.com 2005-05-06 19:50:30 MST ----

I tried that test case with current svn HEAD and it worked fine.



---- Additional Comments From vguzev@yandex.ru 2005-05-08 06:43:24 MST ----

I've just installed Mono 1.1.7 and this sample is still not working 
there... It just hangs on...
But I didn't try the svn version yet.



---- Additional Comments From gonzalo@ximian.com 2005-05-09 18:45:10 MST ----

If on next version you still see this, please, reopen.
Thanks for your time.


Imported an attachment (id=167411)

Unknown bug field "cf_op_sys_details" encountered while moving bug
   <cf_op_sys_details>Linux skif 2.4.25 #2 SMP Fri Apr 23 14:03:00 MSD 2004 i686 athlon i386 GNU/Linux</cf_op_sys_details>