Wrong exception handler called?

Fred Gray fegray@uiuc.edu
Fri May 19 19:21:00 GMT 2000


Hello, folks.

I've spent a day or so working on getting an application that uses the IBM
XML4J parser to run with gcj.  I'm using gcc-2.95.2 plus Bryce McKinlay's patch
with a libgcj snapshot dated May 17 on a Pentium-based single-board computer
running Debian Linux potato.

In the process, I stumbled across what seems to be a serious bug in libgcj's
exception handling.  Under some circumstances, when a single try block has
multiple catch blocks associated with it, the wrong catch block is invoked.

The following test case illustrates the problem:

// Testcase1.java
public class Testcase1 extends Object
{
  public static void main(String args[])
  {
    Testcase2.throwMe();
  }
}

// Testcase2.java
public class Testcase2 extends Object
{
  public static void throwMe2()
  {
      throw new ArrayIndexOutOfBoundsException();
  }

  public static void throwMe()
  {
    try
    {
      throwMe2();
    }
    catch(ArrayIndexOutOfBoundsException e) 
    {
      System.out.println("Exception caught [1]:");
      e.printStackTrace();
    }
    catch(Exception e) 
    {
      System.out.println("Exception caught [2]:");
      e.printStackTrace();
    }
  } 

  public static void main(String args[])
  {
    throwMe();
  }
}

Compiling to class files and running with the Blackdown JDK 1.2.2 gives
this output:

Exception caught [1]:
java.lang.ArrayIndexOutOfBoundsException
        at Testcase2.throwMe2(Testcase2.java, Compiled Code)
        at Testcase2.throwMe(Testcase2.java, Compiled Code)
        at Testcase1.main(Testcase1.java, Compiled Code)

Now compiling the class files to a native executable with 

gcj Testcase1.class Testcase2.class -o Testcase --main=Testcase1 

gives:

Exception caught [2]:
java.lang.ArrayIndexOutOfBoundsException
   at 0x400f8329: java::lang::Throwable::Throwable(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x400ebbb4: java::lang::Exception::Exception(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x400f06e8: java::lang::RuntimeException::RuntimeException(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x400ec8d4: java::lang::IndexOutOfBoundsException::IndexOutOfBoundsException(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x400e89c0: java::lang::ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x0804b174: Testcase2::throwMe2(void) (/home/fegray/testcase/Testcase2.class:0)
   at 0x0804b046: Testcase2::throwMe(void) (/home/fegray/testcase/Testcase2.class:0)
   at 0x0804afab: Testcase1::main(JArray<java::lang::String *> *) (/home/fegray/testcase/Testcase1.class:0)
   at 0x401493e5: gnu::gcj::runtime::FirstThread::run(void) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x401544cf: java::lang::Thread::run_(java::lang::Object *) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x4016504a: _Jv_ThreadSetPriority(_Jv_Thread_t *, int) (/usr/local/gcj/lib/libgcj.so.1)
   at 0x4024f1eb: GC_start_routine (/usr/local/gcj/lib/libgcjgc.so.1)
   at 0x40267c8f: pthread_detach (/lib/libpthread.so.0)
   at 0x403225da: __clone (/lib/libc.so.6)

Interestingly enough, compiling directly from java source to native code 
causes the problem to disappear.  Also, if the main() method from Testcase1 is
merged into Testcase2, the problem goes away.  Consequently, this smells much
more like a compiler problem than like a runtime problem.

Does anyone know whether this issue is fixed in a more current version of
the compiler?  If so, are gcc CVS snapshots generally usable for real work
these days? 

Thanks very much for your help.

-- Fred 


More information about the Java mailing list