Re: gc_add_ref etc.

Date view Thread view Subject view Author view

From: Godmar Back (gback@cs.utah.edu)
Date: Thu Feb 18 1999 - 02:16:21 EST


>
> Godmar Back writes:
> > I put in a temporary fix which allowed me to run Archie's testcase
> > that blew up before.
>
> Thanks for helping me track this down. When I saw your first email
> I was literally doing a binary search of repository snapshots
> between Feb 8 and today... and I was within 21 hours of the bug!! :-)
>

There are shorter ways of finding this. Let me put the first bug back in
and show you what I did. First, you'll notice that it crashes during
marking and that it works with -vmdebug NOGC. Plus, turning on GCDIAG
doesn't make a difference (so it's less likely to be memory corruptiong.)
Let's turn on GCDIAG anyway and add -verbosegc to make sure it happens
during the first gc:

#
# Here's your script, adopted for local use
#
gback@marker [8](~/kaffe/archie) > cat crash.sh
#!/bin/sh

CP=gjc.zip

CLASSPATH=$CP:/x/gback/transvirtual/install/share/kaffe/Klasses.jar
CLASSPATH=$CLASSPATH:classes.zip
export CLASSPATH
#KOPTS=-verbose
KOPTS="-verbosegc -vmdebug GCDIAG"

/x/gback/transvirtual/install-intrp/bin/kaffe $KOPTS gjc.Main -1.1 Block.java

gback@marker [7](~/kaffe/archie) > setenv KAFFE_DEBUG gdb

gback@marker [17](~/kaffe/archie) > sh crash.sh
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-freebsd),
Copyright 1996 Free Software Foundation, Inc...
(gdb) run
Starting program: /x/gback/transvirtual/install-intrp/libexec/Kaffe -verbosegc -vmdebug GCDIAG gjc.Main -1.1 Block.java

Program received signal SIGSEGV, Segmentation fault.
gcMarkObject (gcif=0x5ded8, objp=0x63470)
    at ../../../kaffe/kaffe/kaffevm/mem/gc-incremental.c:215
215 int idx = GCMEM2IDX(info, unit);
(gdb) bt
#0 gcMarkObject (gcif=0x5ded8, objp=0x63470)
    at ../../../kaffe/kaffe/kaffevm/mem/gc-incremental.c:215
#1 0x30c6e in gc_walk_refs (collector=0x5ded8)
    at ../../../kaffe/kaffe/kaffevm/gcRefs.c:119
#2 0x20731 in startGC (gcif=0x5ded8)
    at ../../../kaffe/kaffe/kaffevm/mem/gc-incremental.c:474
#3 0x2041e in gcMan (arg=0x1ea340)
    at ../../../kaffe/kaffe/kaffevm/mem/gc-incremental.c:384
#4 0x3f8b8 in start_this_sucker_on_a_new_frame ()
    at ../../../../../kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c:1129
#5 0x3f9fb in jthread_create (pri=226 'â', func=0x202a4 <gcMan>, daemon=1,
    jlThread=0x1ea340, threadStackSize=32768)
    at ../../../../../kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c:1178
(gdb) p objp
$1 = (void *) 0x63468

#
# So it's crashing when trying to get the index of an object here in
# gc-incremental.c: int idx = GCMEM2IDX(info, unit)
# And this object is a registered root (gcMarkObject called from gc_walk_refs)
# Yet it crashes when trying to determine its allocation type: something must
# be wrong. Either memory corruption or it's not an allocated object at all.
#
# What could it be? The first guess is always some kind of Hjava_lang_Object.
# Note that the object starts at 0x63470, not what gdb says objp is (which
# is 8 lower, gdb is confused because it's still in a register from the
# UTOUNIT) You can see it in the backtrace, though ..., objp=0x63470).
#
# I'm going in small steps:
#

(gdb) p (Hjava_lang_Object*)0x63470
$2 = (Hjava_lang_Object *) 0x63470
(gdb) p *$2
$3 = {dtable = 0x12e110}
(gdb) p $3.dtable
$4 = (dispatchTable *) 0x12e110
(gdb) p *$3.dtable
$5 = {class = 0x1461a0, __dummy0 = 0x0, method = {0x148010}}
(gdb) p *$5.class
$6 = {head = {dtable = 0x12e110}, centry = 0x138448, name = 0x1302d8,
  sourcefile = 0x138598 "Class.java", accflags = 49, superclass = 0x146050,
  constants = {size = 184, tags = 0x1486d8 "", data = 0x1483f8},
  methods = 0x147010, nmethods = 43, msize = 51, fields = 0x0, bfsize = 4,
  nfields = 0, nsfields = 0, dtable = 0x12e110, interfaces = 0x12f3f0,
  if2itable = 0x12f560, itable2dtable = 0x0, interface_len = 1,
  total_interface_len = 1, loader = 0x0, gc_layout = 0x12f550,
  state = 11 '\013', processingThread = 0x12e030, finalizer = 0x0,
  static_data = 0x0}
(gdb) pclass $5.class
java/lang/Class
  implements java/io/Serializable,
  extends java/lang/Object,
was loaded by loader 0x0
state 11

#
# So so. It's an object of type java.lang.Class. Let's see what it is:
#

(gdb) p (Hjava_lang_Class*)$2
$7 = (Hjava_lang_Class *) 0x63470
(gdb) pclass $7
short
  extends
was loaded by loader 0x0
state 0

#
# Hmmm, it's java.lang.Short.TYPE. What happened?
# Look at code... itypes.c:
# Hjava_lang_Class _Jv_shortClass[1];
#
# Indeed:

(gdb) p &_Jv_shortClass
$9 = (Hjava_lang_Class (*)[1]) 0x63470

>From there, you see that &_Jv_shortClass is registered as a reference in
initTypes -> initPrimClass(_Jv_shortClass, "short", 'S', 2);

static
void
initPrimClass(Hjava_lang_Class* clazz, char* name, char sig, int len)
{
        gc_add_ref(clazz);
        ...
}

Since we were looking for a reference to something that's not an allocated
object, that must be it.

By then, I'd already known what's going on: namely that the primitive
classes are no longer gc-allocated.

Then, I removed the call to gc_add_ref and it would crash in the various
places I fixed in gcFuncs.c, for the same reason.
The check I put in gcMarkObject now should detect these errors earlier
in the future.

        - Godmar
  


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Sat Sep 23 2000 - 19:58:10 EDT