JDK-6978918 : Should clear stackTrace before throwing the preallocated default OutOfMemoryError objects
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2010-08-20
  • Updated: 2011-04-08
  • Resolved: 2011-04-08
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The Throwable and its subclasses are mutable. The stack trace and suppressed 
exceptions fields can be set programmatically.  The VM should clear these fields
when the preallocated exceptions are reused.

From Remi Forax:

This code change the stack trace of permanently allocated OutOfMerroryError.

  public static void main(String[] args) {
    Error last = null;

    for(int i=0; i<100; i++) {
      try {
        Object o = new int[Integer.MAX_VALUE];
      } catch (Error e) {
        StackTraceElement[] stackTrace = e.getStackTrace();
        if (stackTrace != null && stackTrace.length>0 && stackTrace[0].getLineNumber() == -3) {
          e.printStackTrace();
          return;
        }

        if (last == e) {
          StackTraceElement element = new StackTraceElement("Foo", "foo", null, -3);
          e.setStackTrace(new StackTraceElement[]{element});
        }
        last = e;
      }
    }
  }

To avoid that the VM has to clear the stacktrace when using the default error:
in universe.cpp, in Universe::gen_out_of_memory_error:

  if (next < 0) {
      // all preallocated errors have been used.
      // return default
+    java_lang_Throwable::clear_stacktrace(default_err);
      return default_err;
    } else { 

And we should do the same for the field suppressed exceptions.

Comments
EVALUATION The preferble solution to this problem is allowing the creation of immutable throwable objects; that will be possible once the fix for 6998871 Support making the Throwable.stackTrace field immutable is available. Closing this bug as will not fix.
08-04-2011

EVALUATION With the fix for 7005628, a Throwable object with a null suppressedExceptions field has that field treated as immutable.
04-04-2011

EVALUATION Enforcing the immutability of the shared exception instances is a better solution than clearing these fields in the VM and that requires specification update.
27-08-2010

PUBLIC COMMENTS As discussed on the mailing lists rather than clearing these fields (which won't work because multiple threads can be throwing the same exception instances) we should enforce the immutability of these shared exception instances. That means, in my view, that: 1. Throwable.setStackTrace should not succeed when called on such an instance 2. Throwable.fillInStackTrace should not succeed when called on such an instance (currently only the shared OutOfMemoryError instances are protected from this) 3. Throwable.addSuppressedException should not succeed when called on such an instance In the case of #1 and #3 and method specifications need updating to reflect this. Note also that #1 and #3, can and should be implemented at the Java level. While #2 is currently done in the VM it too could be done at the Java-level - in which case I suggest switching this bug back to java->java->classes_lang As discussed on the list the simplest solution is to have null indicate "this value can not be modified" - as that is the default value for all pre-allocated instances. Then use sentinel values for "not yet set" values for the fields.
25-08-2010