Bizarre StringBuffer/toHexString bug

Stuart Ballard kaffe@rufus.w3.org
Wed, 29 Aug 2001 17:48:15 -0400


This is really strange.

I'm using the debian package of kaffe, version 1.0.6-3.

At first I thought this was a pure Kaffe bug, but apparently it isn't -
Sun's JVM gives an error too, but it's a different error (a segmentation
fault). And it's not a compiler bug because Jikes and Javac behave the
same way. I found that compiling against Klasses.jar fixed the
segmentation fault on Sun's java but not the misbehavior on kaffe. So to
summarize:

       Klasses.jar  J2re1.3/rt.jar
Kaffe   Exception     Exception
Java     Correct      Segfault

(The columns in this table refer to what the class was *compiled*
against only - when I *ran* the VMs they each used their own classlibs).

I can't for the life of me figure out what's so strange about what I'm
doing that it would cause Sun's JVM to segfault with its own libraries -
or why Kaffe gives this exception. Note that Sun's JVM only fails on
this reduced testcase - the original program that used a more complex
version of this code runs fine under Sun's JVM. But perhaps I'm just
avoiding the segfault through luck in that case.

Any ideas would be much appreciated.

This is the output I get under kaffe:

$ kaffe KaffeBug ce:ccx:attr
1a06
1a06
java.lang.StringIndexOutOfBoundsException
        at java.lang.Throwable.fillInStackTrace(Throwable.java:native)
        at java.lang.Throwable.<init>(Throwable.java:33)
        at java.lang.Exception.<init>(Exception.java:20)
        at java.lang.RuntimeException.<init>(RuntimeException.java:17)
        at
java.lang.IndexOutOfBoundsException.<init>(IndexOutOfBoundsException.java:17)
        at
java.lang.StringIndexOutOfBoundsException.<init>(StringIndexOutOfBoundsException.java:17)
        at java.lang.StringBuffer.append(StringBuffer.java:66)
        at java.lang.StringBuffer.append(StringBuffer.java:46)
        at KaffeBug.main(KaffeBug.java:12)

This is the class I'm using:

class KaffeBug {
  public static void main(String[] args) {
    String result = calcHash();
 
    // This version succeeds.
    System.err.println(result);
 
    // So does this version.
    System.err.println(result.toString());
 
    // This version fails.
    System.err.println("Hash is " + result);
  }
  static String calcHash() {
    StringBuffer sb = new StringBuffer(10);
 
    // Both the use of toHexString() and the replace() are necessary to
make
    // this fail. Hardcoding hx = "1a06" does not fail, and neither does
    // append()ing hx rather than using replace(). There's nothing
terribly
    // special about the number 6662, just what I happened to be trying
for
    // reasons too complex to go into.
    String hx = Integer.toHexString(6662);
    sb.append("0000");
    int len = sb.length();
    sb.replace(len - hx.length(), len, hx);
    return sb.toString();
  }
}