This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
Class initialization crash
- To: java-discuss@sourceware.cygnus.com
- Subject: Class initialization crash
- From: Matt Welsh <mdw@cs.berkeley.edu>
- Date: Tue, 07 Sep 1999 23:26:42 -0700
- Cc: tromey@cygnus.com, Bryce McKinlay <bryce@albatross.co.nz>
- Reply-To: Matt Welsh <mdw@cs.berkeley.edu>
I think I have figured out what's going on with class initialization which
is causing every program I try to run to crash with the latest libgcj.
The problem is I don't see why this is happening.
Here is the chain of events:
1. JvRunMain() calls the INIT_SEGV macro
2. This creates a new NullPointerException
3. This causes class initialization to be started for NullPointerException
4. PrepareCompiledClass() is called with NullPointerException
5. PrepareCompiledClass() does klass->notifyAll() once it has completed
6. notifyAll() does Jv_CondNotifyAll()
7. Jv_CondNotifyAll() calls _Jv_PthreadCheckMonitor()
8. This does pthread_mutex_trylock
9. Now, it checks for (pmu->__m_count == 1). This is TRUE, so
Jv_CondNotifyAll() fails.
10. notifyAll() now wants to throw a new IllegalMonitorStateException.
Since we have to initialize this class, the cycle begins again...
The root problem seems to be that pmu->__m_count is zero when we enter
_Jv_PthreadCheckMonitor. However, the monitor (for NullPointerException,
in this case) was locked in initializeClass(). For some reason, though,
Jv_MonitorEnter (which eventually calls _Jv_MutexLock, which calls
pthread_mutex_lock) is *not* incrementing pmu->__m_count. However,
pthread_mutex_trylock *is* incrementing this value.
Looking at the sources for glibc-2.1.1 it seems that the first time
a mutex is locked, its __m_owner is set to the current thread, and
__m_count is set to 0. So I'm not sure that _Jv_PthreadCheckMonitor
has it right. I don't like the idea of second-guessing the implementation
of pthread mutexes in the first place, so we have to be careful about this.
Tom, what version of glibc/Linux/etc. did you base your implementation on?
Thanks!
Matt Welsh