[kaffe] -O4 jit3 problem

Timothy Stack stack@cs.utah.edu
Tue, 4 Jun 2002 08:51:27 -0600 (MDT)


> I wrote:
> > (*) InternHog seems to fail in the (non-optimized) interp-debug builds
> > now.  Of course, I can't get it to fail when run under GDB... Bah!
> > I'll keep poking at that one.
> 
> This is very bizarre.

i can replicate it here.

> Kaffe seg-faults in string.c:stringCompare, when its passed the
> strings "1812" and "/tmp".  Interestingly, those have the same
> hashcode.  The backtrace is:
>     #0  0x081113de in stringCompare (v1=0x83df800, v2=0x834a878) at ...kaffe/kaffevm/string.c:428
>     #1  0x0813c761 in hashFindSlot (tab=0x832c1c0, ptr=0x83df800) at ...kaffe/kaffevm/hashtab.c:189
>     #2  0x0813c562 in hashRemove (tab=0x832c1c0, ptr=0x83df800) at ...kaffe/kaffevm/hashtab.c:133
>     #3  0x0811122d in stringUninternString (string=0x83df800) at ...kaffe/kaffevm/string.c:352
>     #4  0x08111655 in stringDestroy (collector=0x8215460, obj=0x83df800) at ...kaffe/kaffevm/string.c:539
>     #5  0x080fa325 in finishGC (gcif=0x8215460) at ...kaffe/kaffevm/mem/gc-incremental.c:707
>     #6  0x080f9b6d in gcMan (arg=0x8215460) at ...kaffe/kaffevm/mem/gc-incremental.c:527
>     #7  0x08113547 in startSpecialThread (arg=0x8335c20) at ...kaffe/kaffevm/thread.c:273
> 
> Here are the strings:
> (gdb) p* s1
> $1 = {base = {dtable = 0x82e9c60, lock = 0x0}, value = 0x83defb0, offset = 0, count = 4, interned = 1 '\001', 
>   hash = 1515144}
> (gdb) p* s2
> $2 = {base = {dtable = 0x82e9c60, lock = 0x0}, value = 0x8346f18, offset = 0, count = 4, interned = 1 '\001', 
>   hash = 1515144}
> 
> They're both intern'd strings.  s1 is the string being destroyed by the GC.
> 
> The SEGV occurs on the first dereference of the zero'th byte of one of
> the strings.  (My x86 assembly isn't very keen, here's a chunk of the
> disassembly.)
> 
> ...
> 0x81113d6 <stringCompare+230>:  jmp    0x8111400 <stringCompare+272>
> 0x81113d8 <stringCompare+232>:  mov    0xfffffff0(%ebp),%eax
> 0x81113db <stringCompare+235>:  mov    0xffffffec(%ebp),%edx
> 0x81113de <stringCompare+238>:  movzwl (%eax),%eax
> 0x81113e1 <stringCompare+241>:  cmp    (%edx),%ax
> 0x81113e4 <stringCompare+244>:  je     0x81113f0 <stringCompare+256>
> 0x81113e6 <stringCompare+246>:  mov    $0x1,%eax
> 0x81113eb <stringCompare+251>:  jmp    0x8111404 <stringCompare+276>
> ...
> 
> eip is on the movzwl instruction.  eax is 0x83defbc.  ebp is valid.

I can't dereference the arrays here:

$5 = {base = {dtable = 0x81a1c38, lock = 0x0}, value = 0x8290fb0, offset =
0, count = 4, interned = 1 '\001',
  hash = 1515144}
(gdb) p $4.value
$6 = (HArrayOfChar *) 0x8290fb0
(gdb) p $4.value[0]
Error accessing memory address 0x8290fb0: Bad address.
(gdb) p $4.value[1]

So, is it possible for the character array to be freed before the string?

> Adding code to check if the two arguments to stringCompare were
> intern'd, and then seeing if they're == or not fixes the problem
> because it avoids the dereference of the string contents....  Adding
> printfs to the code indicates that this is the *only* time that two
> intern'd strings are passed to stringCompare.  I can't see any reason
> why intern'd strings would cause a seg-fault, though.
> 
> I guess I'm curious if anyone else can reproduce this problem, and if
> anyone else has any ideas as to what might be going wrong.  (Or can
> justify the fix from the previous paragraph.)

Not sure if the fix is valid.  If they can be freed before the string,
then you'd have to avoid dereferencing all interned strings here...

> -Pat

tim