This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
RE: TestLeak crashes due to GC issues
- From: "Boehm, Hans" <hans dot boehm at hp dot com>
- To: "Ulrich Weigand" <uweigand at de dot ibm dot com>, <java at gcc dot gnu dot org>
- Date: Tue, 30 Nov 2004 14:34:59 -0800
- Subject: RE: TestLeak crashes due to GC issues
This is on Linux on a 390/zSeries? Current CVS?
I assume this is distinct from the test failures associated with Bryce's
patch?
It does sound like the collector not tracing the argument to
the thread start function.
Here's why I think this shouldn't be possible:
The pthread_create call should really be directed to GC_pthread_create,
since gc.h #defines pthread_create. GC_pthread_create in
pthread_support.c stores the argument in *si,
which is allocated with GC_INTERNAL_MALLOC, and should be
traced by the GC. It then calls the real pthread_create.
This is followed by a wait on a semaphore which is allocated
in *si. The sem_post is executed by the child after it is
registered with the collector, and the argument is visible
to the collector from the child thread.
It's probably worth stepping through thread creation once, and making
sure that GC_pthread_create is called as expected.
It might also be worth looking at the object code for GC_pthread_create
to make sure that the compiler isn't hiding si somewhere the collector
can't find it.
Hans
> -----Original Message-----
> From: java-owner@gcc.gnu.org
> [mailto:java-owner@gcc.gnu.org]On Behalf Of
> Ulrich Weigand
> Sent: Saturday, November 27, 2004 8:17 AM
> To: java@gcc.gnu.org
> Subject: TestLeak crashes due to GC issues
>
>
> Hello,
>
> I'm seeing an occasional crash when executing the TestLeak libjava
> test case. The crash happens when starting a new thread; in the
> routine really_start:
>
> static void *
> really_start (void *x)
> {
> struct starter *info = (struct starter *) x;
> _Jv_ThreadRegister (info->data);
>
> the info->data pointer is corrupted, and thus _Jv_ThreadRegister
> crashes.
>
> This pointer was set up from _Jv_ThreadStart:
>
> void
> _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
> _Jv_ThreadStartFunc *meth)
> {
> [...]
> info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
> info->method = meth;
> info->data = data;
> [...]
> int r = pthread_create (&data->thread, &attr, really_start,
> (void *) info);
>
> Note how 'info' is allocated as garbage-collectable memory
> using _Jv_AllocBytes.
>
>
> When the crash happens, the info->data member get corrupted
> from within the _Jv_NewPrimArray function:
>
> __JArray *arr =
> (__JArray*) _Jv_AllocPtrFreeObj (size + elsize * count, klass);
> memset((char *)arr + size, 0, elsize * count);
>
> jsize *lp = const_cast<jsize *> (&arr->length);
> *lp = count;
>
> because the _Jv_AllocPtrFreeObj call returns the same pointer
> as the _Jv_AllocBytes call returned. As arr->length resides
> at offset 8, just like info->data does, the final assignment
> clobbers the top half of the info->data pointer.
>
>
> I'm guessing now that a garbage collection run happened to
> hit while the creation of the new thread was 'in flight',
> and for some reason the memory pointed to by 'info' was
> not recognized as in-use.
>
> Now, my first question is, is the garbage collector
> *supposed* to recognize this memory is in use? There is
> no pointer from any Java data structure to this memory;
> the only reference at this point is from somewhere inside
> libpthread's thread descriptor (which happens to reside
> on the thread stack of the not-yet-fully-initialized
> new thread). Should the GC known about this?
>
> If yes, any suggestions why this might not work?
> If no, shouldn't _Jv_ThreadStart be changed to use
> some other allocation mechanism?
>
> Bye,
> Ulrich
>
> --
> Dr. Ulrich Weigand
> Linux on zSeries Development
> Ulrich.Weigand@de.ibm.com
>