JDK-4217960 : [native stack overflow bug] reflection test causes crash
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.1,1.1.6,1.2.0,1.3.1,1.4.0
  • Priority: P5
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS:
    generic,linux,solaris_2.4,solaris_2.5.1,solaris_2.6,windows_95,windows_nt generic,linux,solaris_2.4,solaris_2.5.1,solaris_2.6,windows_95,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1999-03-06
  • Updated: 2006-06-20
  • Resolved: 2006-06-20
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description
The following program causes JDK1.1.8 and JDK1.2 to crash.

import java.applet.*;
import java.lang.Class;
import java.lang.reflect.*;

public class Test implements Runnable {

    static int depth = 0;
    static Method m;

    public static void test(Method m) throws Throwable {
        ++depth;
        System.err.println("Test at depth " + depth);

        Object[] args = {m};
        try {
            m.invoke(null, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    public void run() {
        try {
            Class c = Test.class;
            Class[] sig = {Method.class};
            m = c.getMethod("test", sig);
            test(m);
        } catch (InvocationTargetException e) {
            System.err.println("InvocationTargetException occurred.");
            e.printStackTrace();
            e.getTargetException().printStackTrace();
        } catch (Throwable e) {
            System.err.println("Exception occurred.");
            e.printStackTrace();
        }
        System.err.println("depth " + depth);
    }

    public static void main(String[] args) {
        new Thread(new Test()).start();
    }
}

It purposely runs in a separate thread so that it gets a new native
C stack.  For Solaris, this is smaller than the main thread's
stack, so the test crashes quickly without eating up all your
swap space.

dean.long@Eng 1999-03-06

Name: skR10017			Date: 04/21/2000



The same test crashes linux VM with Segmentation Fault error.
 
======================================================================

Name: krC82822			Date: 07/15/2001


[1.3.1 and 1.4 beta build 65 on Linux]

1.) Write some kind of endless indirect recursion (a calls b, b calls a). In my
case it was a FilterInputStream where read(b[],ofs,len) calls read(b[]).
2.) Run the program.

As soon as control flow gets to the point, the JVM crashes with a segmentation
violation signal. The correct behaviour would be to throw a StackOverflowException.
I was really confused about the JVM crash and couldn't find the problem.

IBM's Linux JVM handles the problem correctly and throws a nice stack dump.
(Review ID: 128094)
======================================================================

Comments
EVALUATION Addressed in later releases. If this needs to be addressed in older releases then an escalation needs to be filed.. Closing/unverified..
20-06-2006

SUGGESTED FIX Possible solutions: 1) Fix current C stack overflow checks. Under PersonalJava, this test exits with a StackOverflowError 2) Implement java.lang.Method.invoke so that it does not cause C stack recursion, just Java stack recursion. (I have a prototype of how this would work) 3) Grow C stacks (JavaOS)
11-06-2004

EVALUATION There are many bugs filed against native stack overflow all of which discuss different ways of calling recursive code with a native method activation at the C stack top that steps off the end of the C stack. I am keeping this one bug open and closing the others as duplicates of it. At the time of this writing I'll be closing 4027933, 4134353, 4222359 (they are all slightly different, but the issue is the same). stack overflow stack overflow stack overflow stack overflow (for the benefit of the robots). anand.palaniswamy@Eng 1999-04-09 Note that 4134353 has a discussion of sysThreadCheckStack. anand.palaniswamy@Eng 1999-04-09 ------------------------------------ Putting ThrowStackOverflowError(0,0); in the invoke() method in jvm.c or do_execute_java_method_vararg() in interpreter.c , seems to alleviate the problem of SEGV in the native code for invoke() as there is a red zone check here and an StackOVerflowException is thrown from the native code. But while doing the stack unwinding for the recursive calls, if there are direct/indirect native calls, then again a SEGV happens (For ex: System.err.println("Test at depth "+depth);). If there are no native calls while doing stack unwinding, the code throws a proper StackOverflowError, before exiting. ###@###.### 2001-08-14 This is fixed in the current putback for hotspot (mantis 1.4.2 release). I've been closing the later variants of this bug as a duplicate of 4697667 and so the test program in this bug report is fixed too. The fix is to bang a number of stack pages ahead in compiled and interpreted entry code where the number is determined by the depth of the C code. The StackShadowPages can be increased for cases where the C code is deeper with this -XX:StackShadowPages command line option. Most of the C/C++ code from the VM or native uses around 3 pages of stack at it's deepest, so that is what the value is set to now. If a backport of this fix is required, see information in bugid 4697667 . ###@###.### 2002-10-16
16-10-2002