# HG changeset patch # User coleenp # Date 1460158772 14400 # Node ID eea810d6f7889e6d6382ba33efaa0132a299e3c6 # Parent f8fd0bcc60af3a0295970318f22211de4dced248 8033735: make Throwable.backtrace visible to Class.getDeclaredField again Summary: removed old hack to workaround an old crash. Reviewed-by: hseigel, twisti, mchung diff -r f8fd0bcc60af -r eea810d6f788 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Apr 07 15:34:21 2016 -0700 +++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Apr 08 19:39:32 2016 -0400 @@ -1818,9 +1818,6 @@ // Ensure class is linked k->link_class(CHECK_NULL); - // 4496456 We need to filter out java.lang.Throwable.backtrace - bool skip_backtrace = false; - // Allocate result int num_fields; @@ -1831,11 +1828,6 @@ } } else { num_fields = k->java_fields_count(); - - if (k() == SystemDictionary::Throwable_klass()) { - num_fields--; - skip_backtrace = true; - } } objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL); @@ -1844,12 +1836,6 @@ int out_idx = 0; fieldDescriptor fd; for (JavaFieldStream fs(k); !fs.done(); fs.next()) { - if (skip_backtrace) { - // 4496456 skip java.lang.Throwable.backtrace - int offset = fs.offset(); - if (offset == java_lang_Throwable::get_backtrace_offset()) continue; - } - if (!publicOnly || fs.access_flags().is_public()) { fd.reinitialize(k(), fs.index()); oop field = Reflection::new_field(&fd, CHECK_NULL); diff -r f8fd0bcc60af -r eea810d6f788 hotspot/test/runtime/Throwable/ThrowableIntrospectionSegfault.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Throwable/ThrowableIntrospectionSegfault.java Fri Apr 08 19:39:32 2016 -0400 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016, 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 8033735 + * @summary check backtrace field introspection + * @library /testlibrary + * @run main ThrowableIntrospectionSegfault + */ + +import java.lang.reflect.*; + +public class ThrowableIntrospectionSegfault { + public static void main(java.lang.String[] unused) { + // Construct a throwable object. + Throwable throwable = new Throwable(); + throwable.fillInStackTrace(); + + // Retrieve a reflection handle to the private backtrace field. + Class class1 = throwable.getClass(); + Field field; + try { + field = class1.getDeclaredField("backtrace"); + } + catch (NoSuchFieldException e) { + System.err.println("Can't retrieve field handle Throwable.backtrace: " + e.toString()); + return; + } + field.setAccessible(true); + + // Retrieve the value of the backtrace field. + Object backtrace; + try { + backtrace = field.get(throwable); + } + catch (IllegalAccessException e) { + System.err.println( "Can't retrieve field value for Throwable.backtrace: " + e.toString()); + return; + } + + try { + + // Retrieve the class of throwable.backtrace[0][0]. + Class class2 = ((Object[]) ((Object[]) backtrace)[2])[0].getClass(); + + // Segfault occurs while executing this line, to retrieve the name of + // this class. + String class2Name = class2.getName(); + + System.err.println("class2Name=" + class2Name); + return; // pass! Passes if it doesn't crash. + } catch (ClassCastException e) { + // Passes if it doesn't crash. Also if the backtrace changes this test might get + // ClassCastException and that's ok too. + System.out.println("Catch exception " + e); + return; // pass! Passes if it doesn't crash. + } + } +}