changeset 3473:04ade88d9712

6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K Reviewed-by: sspitsyn, dholmes, coleenp, kamg
author fparain
date Mon, 09 Jul 2012 01:28:37 -0700
parents 5a1f452f8f90
children 90d5a592ea8f
files agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java src/share/vm/classfile/classFileParser.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/instanceKlassKlass.cpp src/share/vm/prims/jvmtiClassFileReconstituter.cpp src/share/vm/prims/jvmtiEnv.cpp src/share/vm/prims/jvmtiRedefineClasses.cpp src/share/vm/runtime/vmStructs.cpp test/runtime/6294277/SourceDebugExtension.java test/runtime/6294277/Test6294277.sh
diffstat 12 files changed, 273 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Thu Jun 28 11:37:28 2012 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Mon Jul 09 01:28:37 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -688,8 +688,7 @@
         if (sde == null) {
            String extension = null;
            if (saKlass instanceof InstanceKlass) {
-              Symbol sdeSym = ((InstanceKlass)saKlass).getSourceDebugExtension();
-              extension = (sdeSym != null)? sdeSym.asString() : null;
+              extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
            }
            if (extension == null) {
               sde = NO_SDE_INFO_MARK;
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Jun 28 11:37:28 2012 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Jul 09 01:28:37 2012 -0700
@@ -342,7 +342,7 @@
   public Oop       getProtectionDomain()    { return                protectionDomain.getValue(this); }
   public ObjArray  getSigners()             { return (ObjArray)     signers.getValue(this); }
   public Symbol    getSourceFileName()      { return getSymbol(sourceFileName); }
-  public Symbol    getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
+  public String    getSourceDebugExtension(){ return                CStringUtilities.getString(sourceDebugExtension.getValue(getHandle())); }
   public TypeArray getInnerClasses()        { return (TypeArray)    innerClasses.getValue(this); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
   public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/classfile/classFileParser.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -2337,12 +2337,7 @@
 
   // Don't bother storing it if there is no way to retrieve it
   if (JvmtiExport::can_get_source_debug_extension()) {
-    // Optimistically assume that only 1 byte UTF format is used
-    // (common case)
-    TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
-    k->set_source_debug_extension(sde_symbol);
-    // Note that set_source_debug_extension() increments the reference count
-    // for its copy of the Symbol*, so use a TempNewSymbol here.
+    k->set_source_debug_extension((char*)sde_buffer, length);
   }
   // Got utf8 string, set stream position forward
   cfs->skip_u1(length, CHECK);
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/oops/instanceKlass.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -847,7 +847,6 @@
   Klass::shared_symbols_iterate(closure);
   closure->do_symbol(&_generic_signature);
   closure->do_symbol(&_source_file_name);
-  closure->do_symbol(&_source_debug_extension);
 
   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
     int name_index = fs.name_index();
@@ -1944,9 +1943,10 @@
   // class can't be referenced anymore).
   if (_array_name != NULL)  _array_name->decrement_refcount();
   if (_source_file_name != NULL) _source_file_name->decrement_refcount();
-  if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount();
   // walk constant pool and decrement symbol reference counts
   _constants->unreference_symbols();
+
+  if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
 }
 
 void instanceKlass::set_source_file_name(Symbol* n) {
@@ -1954,9 +1954,22 @@
   if (_source_file_name != NULL) _source_file_name->increment_refcount();
 }
 
-void instanceKlass::set_source_debug_extension(Symbol* n) {
-  _source_debug_extension = n;
-  if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount();
+void instanceKlass::set_source_debug_extension(char* array, int length) {
+  if (array == NULL) {
+    _source_debug_extension = NULL;
+  } else {
+    // Adding one to the attribute length in order to store a null terminator
+    // character could cause an overflow because the attribute length is
+    // already coded with an u4 in the classfile, but in practice, it's
+    // unlikely to happen.
+    assert((length+1) > length, "Overflow checking");
+    char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
+    for (int i = 0; i < length; i++) {
+      sde[i] = array[i];
+    }
+    sde[length] = '\0';
+    _source_debug_extension = sde;
+  }
 }
 
 address instanceKlass::static_field_addr(int offset) {
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/oops/instanceKlass.hpp	Mon Jul 09 01:28:37 2012 -0700
@@ -226,7 +226,9 @@
   // Name of source file containing this klass, NULL if not specified.
   Symbol*         _source_file_name;
   // the source debug extension for this klass, NULL if not specified.
-  Symbol*         _source_debug_extension;
+  // Specified as UTF-8 string without terminating zero byte in the classfile,
+  // it is stored in the instanceklass as a NULL-terminated UTF-8 string
+  char*           _source_debug_extension;
   // Generic signature, or null if none.
   Symbol*         _generic_signature;
   // Array name derived from this class which needs unreferencing
@@ -542,8 +544,8 @@
   void set_major_version(u2 major_version) { _major_version = major_version; }
 
   // source debug extension
-  Symbol* source_debug_extension() const   { return _source_debug_extension; }
-  void set_source_debug_extension(Symbol* n);
+  char* source_debug_extension() const     { return _source_debug_extension; }
+  void set_source_debug_extension(char* array, int length);
 
   // symbol unloading support (refcount already added)
   Symbol* array_name()                     { return _array_name; }
--- a/src/share/vm/oops/instanceKlassKlass.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/oops/instanceKlassKlass.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -421,8 +421,7 @@
     ik->set_protection_domain(NULL);
     ik->set_signers(NULL);
     ik->set_source_file_name(NULL);
-    ik->set_source_debug_extension(NULL);
-    ik->set_source_debug_extension(NULL);
+    ik->set_source_debug_extension(NULL, 0);
     ik->set_array_name(NULL);
     ik->set_inner_classes(NULL);
     ik->set_static_oop_field_count(0);
@@ -531,7 +530,7 @@
   }
   if (ik->source_debug_extension() != NULL) {
     st->print(BULLET"source debug extension:       ");
-    ik->source_debug_extension()->print_value_on(st);
+    st->print_cr("%s", ik->source_debug_extension());
     st->cr();
   }
 
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -268,14 +268,18 @@
 // JSR45|   SourceDebugExtension_attribute {
 // JSR45|       u2 attribute_name_index;
 // JSR45|       u4 attribute_length;
-// JSR45|       u2 sourcefile_index;
+// JSR45|       u1 debug_extension[attribute_length];
 // JSR45|   }
 void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
   assert(ikh()->source_debug_extension() != NULL, "caller must check");
 
   write_attribute_name_index("SourceDebugExtension");
-  write_u4(2);  // always length 2
-  write_u2(symbol_to_cpool_index(ikh()->source_debug_extension()));
+  int len = (int)strlen(ikh()->source_debug_extension());
+  write_u4(len);
+  u1* ext = (u1*)ikh()->source_debug_extension();
+  for (int i=0; i<len; i++) {
+    write_u1(ext[i]);
+  }
 }
 
 // Write (generic) Signature attribute
--- a/src/share/vm/prims/jvmtiEnv.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/prims/jvmtiEnv.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2541,15 +2541,12 @@
     if (!Klass::cast(k)->oop_is_instance()) {
       return JVMTI_ERROR_ABSENT_INFORMATION;
     }
-    Symbol* sdeOop = instanceKlass::cast(k)->source_debug_extension();
-    NULL_CHECK(sdeOop, JVMTI_ERROR_ABSENT_INFORMATION);
+    char* sde = instanceKlass::cast(k)->source_debug_extension();
+    NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
 
     {
-      JavaThread* current_thread  = JavaThread::current();
-      ResourceMark rm(current_thread);
-      const char* sdecp = (const char*) sdeOop->as_C_string();
-      *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sdecp)+1);
-      strcpy(*source_debug_extension_ptr, sdecp);
+      *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
+      strcpy(*source_debug_extension_ptr, sde);
     }
   }
 
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3236,7 +3236,9 @@
 
   // Copy the "source debug extension" attribute from new class version
   the_class->set_source_debug_extension(
-    scratch_class->source_debug_extension());
+    scratch_class->source_debug_extension(),
+    scratch_class->source_debug_extension() == NULL ? 0 :
+    (int)strlen(scratch_class->source_debug_extension()));
 
   // Use of javac -g could be different in the old and the new
   if (scratch_class->access_flags().has_localvariable_table() !=
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Jun 28 11:37:28 2012 +0200
+++ b/src/share/vm/runtime/vmStructs.cpp	Mon Jul 09 01:28:37 2012 -0700
@@ -308,7 +308,7 @@
   nonstatic_field(instanceKlass,               _protection_domain,                            oop)                                   \
   nonstatic_field(instanceKlass,               _signers,                                      objArrayOop)                           \
   nonstatic_field(instanceKlass,               _source_file_name,                             Symbol*)                               \
-  nonstatic_field(instanceKlass,               _source_debug_extension,                       Symbol*)                               \
+  nonstatic_field(instanceKlass,               _source_debug_extension,                       char*)                                 \
   nonstatic_field(instanceKlass,               _inner_classes,                                typeArrayOop)                          \
   nonstatic_field(instanceKlass,               _nonstatic_field_size,                         int)                                   \
   nonstatic_field(instanceKlass,               _static_field_size,                            int)                                   \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6294277/SourceDebugExtension.java	Mon Jul 09 01:28:37 2012 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6294277
+ * @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
+ */
+import java.io.*;
+
+public class SourceDebugExtension extends ClassLoader
+{
+    static final int attrSize = 68000;
+    static byte[] header = {
+(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x32, (byte)0x00, (byte)0x1e, (byte)0x0a, (byte)0x00, (byte)0x06, (byte)0x00,
+(byte)0x0f, (byte)0x09, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x08,
+(byte)0x00, (byte)0x12, (byte)0x0a, (byte)0x00, (byte)0x13, (byte)0x00, (byte)0x14,
+(byte)0x07, (byte)0x00, (byte)0x15, (byte)0x07, (byte)0x00, (byte)0x16, (byte)0x01,
+(byte)0x00, (byte)0x06, (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74,
+(byte)0x3e, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56,
+(byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, (byte)0x6f, (byte)0x64, (byte)0x65,
+(byte)0x01, (byte)0x00, (byte)0x0f, (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65,
+(byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, (byte)0x65, (byte)0x72, (byte)0x54,
+(byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x04,
+(byte)0x6d, (byte)0x61, (byte)0x69, (byte)0x6e, (byte)0x01, (byte)0x00, (byte)0x16,
+(byte)0x28, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
+(byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
+(byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x29,
+(byte)0x56, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x53, (byte)0x6f, (byte)0x75,
+(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, (byte)0x6c, (byte)0x65,
+(byte)0x01, (byte)0x00, (byte)0x0d, (byte)0x54, (byte)0x65, (byte)0x73, (byte)0x74,
+(byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x2e, (byte)0x6a, (byte)0x61,
+(byte)0x76, (byte)0x61, (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08,
+(byte)0x07, (byte)0x00, (byte)0x17, (byte)0x0c, (byte)0x00, (byte)0x18, (byte)0x00,
+(byte)0x19, (byte)0x01, (byte)0x00, (byte)0x34, (byte)0x54, (byte)0x65, (byte)0x73,
+(byte)0x74, (byte)0x20, (byte)0x70, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x72,
+(byte)0x61, (byte)0x6d, (byte)0x20, (byte)0x66, (byte)0x6f, (byte)0x72, (byte)0x20,
+(byte)0x62, (byte)0x69, (byte)0x67, (byte)0x20, (byte)0x53, (byte)0x6f, (byte)0x75,
+(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65, (byte)0x62, (byte)0x75,
+(byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65, (byte)0x6e, (byte)0x73,
+(byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x61, (byte)0x74, (byte)0x74,
+(byte)0x72, (byte)0x69, (byte)0x62, (byte)0x75, (byte)0x74, (byte)0x65, (byte)0x73,
+(byte)0x07, (byte)0x00, (byte)0x1a, (byte)0x0c, (byte)0x00, (byte)0x1b, (byte)0x00,
+(byte)0x1c, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x54, (byte)0x65, (byte)0x73,
+(byte)0x74, (byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x01, (byte)0x00,
+(byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
+(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a,
+(byte)0x65, (byte)0x63, (byte)0x74, (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a,
+(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e,
+(byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x79, (byte)0x73, (byte)0x74, (byte)0x65,
+(byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x6f, (byte)0x75, (byte)0x74,
+(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
+(byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f, (byte)0x50, (byte)0x72,
+(byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x65,
+(byte)0x61, (byte)0x6d, (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x13, (byte)0x6a,
+(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f,
+(byte)0x50, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74,
+(byte)0x72, (byte)0x65, (byte)0x61, (byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x07,
+(byte)0x70, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x6c, (byte)0x6e,
+(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x28, (byte)0x4c, (byte)0x6a, (byte)0x61,
+(byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
+(byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
+(byte)0x3b, (byte)0x29, (byte)0x56, (byte)0x01, (byte)0x00, (byte)0x14, (byte)0x53,
+(byte)0x6f, (byte)0x75, (byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65,
+(byte)0x62, (byte)0x75, (byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65,
+(byte)0x6e, (byte)0x73, (byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x00, (byte)0x21,
+(byte)0x00, (byte)0x05, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x07,
+(byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, (byte)0xb7, (byte)0x00,
+(byte)0x01, (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00,
+(byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
+(byte)0x0b, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0x00, (byte)0x02, (byte)0x00,
+(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0xb2, (byte)0x00,
+(byte)0x02, (byte)0x12, (byte)0x03, (byte)0xb6, (byte)0x00, (byte)0x04, (byte)0xb1,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0x00,
+(byte)0x02, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+(byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x09,
+(byte)0xa0
+  };
+
+    public static void main(String[] args) throws Exception
+    {
+        try {
+            SourceDebugExtension loader = new SourceDebugExtension();
+            /* The test program creates a class file from the header
+             * stored above and adding the content of a SourceDebugExtension
+             * attribute made of the character 0x02 repeated 68000 times.
+             * This attribute doesn't follow the syntax specified in JSR 45
+             * but it's fine because this test just checks that the JVM is
+             * able to load a class file with a SourceDebugExtension
+             * attribute bigger than 64KB. The JVM doesn't try to
+             * parse the content of the attribute, this work is performed
+             * by the SA or external tools.
+             */
+            byte[] buf = new byte[header.length + attrSize];
+            for(int i=0; i<header.length; i++) {
+                buf[i] = header[i];
+            }
+            for(int i=0; i<attrSize; i++) {
+                buf[header.length+i] = (byte)0x02;
+            }
+            Class c = loader.defineClass("TestProg", buf, 0, buf.length);
+            System.out.println("Test PASSES");
+        } catch(Exception e) {
+            System.out.println("Test FAILS");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6294277/Test6294277.sh	Mon Jul 09 01:28:37 2012 -0700
@@ -0,0 +1,92 @@
+# 
+#  Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+# 
+
+ 
+# @test Test6294277.sh
+# @bug 6294277
+# @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
+# @run shell Test6294277.sh
+#
+
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+  PARENT=`dirname \`which java\``
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA not set, selecting " ${TESTJAVA}
+  echo "If this is incorrect, try setting the variable manually."
+fi
+
+BIT_FLAG=""
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ## for solaris, linux it's HOME
+    FILE_LOCATION=$HOME
+    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" -a `uname -p`='sparc' ]
+    then
+        BIT_FLAG="-d64"
+    fi
+    ;;
+  Windows_* | Darwin )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    echo "Test skipped"
+    exit 0
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+cp ${TESTSRC}${FS}*.java .
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
+
+${TESTJAVA}${FS}bin${FS}javac *.java
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -classpath . -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension > test.out 2>&1 &
+
+P_PID=$!
+
+sleep 60
+STATUS=1
+
+grep "Test PASSES" test.out > ${NULL}
+if [ $? = 0 ]; then
+    cat test.out
+    STATUS=0
+fi
+
+exit $STATUS