JDK-4185411 : Various crashes when using recursive reflection.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.1.6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_95
  • CPU: x86
  • Submitted: 1998-10-29
  • Updated: 1999-04-12
  • Resolved: 1999-04-12
Related Reports
Duplicate :  
Relates :  
Description

Name: ap32198			Date: 10/29/98


In the following (utterly pointless) bits of
code, the Method class's invoke method is
invoked, with the args set up in such a way that
this carries on recursively. What I thought
would happen would be the throwing of a
StackOverFlowError wrapped up in lots of
InvocationTargetExceptions, and on Linux and
Solaris (JDK 1.1.13beta) this is what happens,
with the Error 7801 layers down in all the
wrappers.

However, on Win95 (JDK 1.1.6) various errors
occur. The first version of the code has the
variables static to the class and set up
by static initializer:

import java.lang.reflect.*;

public class Boom {
  public static void main(String[] cmdline) throws Throwable {
    System.out.println("In main.");
    try {
      method.invoke(method, args); // "recursive reflection"
      // should throw exception before we reach here.
      System.out.println("how did I get here?");
    }
    catch(Throwable t) {
      int layers;
      for(layers = 0; t instanceof InvocationTargetException; layers++)
        t = ((InvocationTargetException)t).getTargetException();

      System.err.println("Found " + layers + " layers of wrappers.");
      throw t;
    }
    finally {
      System.out.println("finally block in main.");
    }
  }

  static final Method method; static final Object[] args;
  static final Class[] invokeParams = { Object.class, Object[].class };

  static {
    System.out.println("start of static.");
    try {
      method = Method.class.getMethod("invoke", invokeParams);
      args = new Object[] { method, null };
      args[1] = args;
    }
    catch(Throwable t) {
      throw new ExceptionInInitializerError(t);
    }
    finally {
      System.out.println("finally block in static.");
    }
  }
}

This goes through the static{} block OK with
output in the right places, but when we enter
main() I just get "In main." before one of the
following happens:

(when I say "bluescreen" I mean the screen goes
blue (duh) and I get a string of warnings of
fatal exception 0E until my PC locks up and I
hard-reboot.)
1) Program exits with no warning message, (no
output about main()'s finally block) and the
DOS window works fine until I try to switch
tasks, whereupon bluescrenn;
2) System bluescreens after a few seconds;
3) I get a windows errmsg box with Close/Details
buttons, except that  frequently a button is
missing, or there but invisible, or the details
(register, stack dump etc) are partially written
in the msgbox background colour so I can't read
them until I select the text with the mouse.

In the second version, I have all the parameters
local to main():

import java.lang.reflect.*;

public class Boom2 {
  public static void main(String[] cmdline) throws Throwable {
    System.out.println("In main.");

    try{
      final Method method = Method.class.getMethod("invoke",
              new Class[] { Object.class, Object[].class });

      final Object[] args = new Object[] { method, null };
      args[1] = args;

      method.invoke(method, args); // "recursive reflection"
      // exception should have been thrown by now...
      System.out.println("how did I get here?");
    }
    catch(Throwable t) {
      int layers;
      for(layers = 0; t instanceof InvocationTargetException; layers++)
        t = ((InvocationTargetException)t).getTargetException();

      System.err.println("Found " + layers + " layers of wrappers.");
      throw t;
    }
    finally {
      System.out.println("finally block in main.");
    }
  }
}

This one always (so far) produces a well-formed
errmsg box, and it seems that after I run Boom2,
Boom is perhaps a bit more likely to give me
an errmsg box than a blue screen.

An errmsg from Boom2 is given below:

JAVA caused a stack fault in module JAVAI.DLL at
0137:10032c9e.
Registers:
EAX=00000001 CS=0137 EIP=10032c9e EFLGS=00010213
EBX=006de7f0 SS=013f ESP=00542000 EBP=00000000
ECX=00e64198 DS=013f ESI=006de818 FS=279f
EDX=00e64198 ES=013f EDI=006de81c GS=0000
Bytes at CS:EIP:
ff 15 74 a3 05 10 c3 8d 64 24 00 8d a4 24 00 00 
Stack dump:
00000001 100332b5 1000dbc5 10021e4c 00000000
006de81c 006de818 006de7f0 00eaf434 1001028c
100408a9 00e64198 00e64198 00e64190 006de818
00542090
(Review ID: 30750)
======================================================================

Comments
WORK AROUND Name: ap32198 Date: 10/29/98 Never, ever, write code that is as stupid as this in any real project. ======================================================================
11-06-2004

EVALUATION I can reproduce this 1.1.x. It seems fixed in 1.2. But this is a good, one to add as a regression tests. anand.palaniswamy@Eng 1998-11-04 Added test to 1.2. anand.palaniswamy@Eng 1999-04-12
04-11-1998