test/jdk/com/sun/jdi/BacktraceFieldTest.java
changeset 47216 71c04702a3d5
parent 44423 306c020eb154
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/BacktraceFieldTest.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2001, 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 4446677
+ * @bug 8158237
+ * @summary debuggee used to crash when debugging under jbuilder
+ * @author jjh
+ *
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter
+ * @run compile -g BacktraceFieldTest.java
+ * @run driver BacktraceFieldTest
+ */
+
+/*
+ * The fix for this bug filters out the backtrace field from the list
+ * of fields for java.lang.Throwable.
+ * This test verifies that this really happens, and also verifies that the fix
+ * doesn't incorrectly discard other fields.
+ */
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/********** target program **********/
+
+class Testy {
+    /*
+     * This is used to verify that the fix doesn't filter out fields that it
+     * shouldn't.  7 is an abitrary number, and this isn't a definitive
+     * test; the fix could conceivably filter out the 89th field of a class
+     * named Foo.
+     * To verify that this part of this test works, first uncomment the field8
+     * line and verify that the test fails, and then rename a field to xxx and
+     * verify that the test fails.
+     */
+    int field1;
+    int field2;
+    int field3;
+    int field4;
+    int field5;
+    int field6;
+    final static int field7 = 7;  // Value is the number of fields.
+    //int field8;
+
+    Testy() {
+    }
+}
+
+
+class BacktraceFieldTarg {
+    public static void gus() {
+    }
+
+    public static void main(String[] args) {
+        Testy myTesty = new Testy();
+        try {
+            throw new RuntimeException("jjException");
+        } catch (Exception ee) {
+            gus();
+            System.out.println("debuggee: Exception: " + ee);
+        }
+    }
+}
+
+/********** test program **********/
+
+public class BacktraceFieldTest extends TestScaffold {
+    ThreadReference mainThread;
+
+    BacktraceFieldTest (String args[]) {
+        super(args);
+    }
+
+    public static void main(String[] args)      throws Exception {
+        new BacktraceFieldTest(args).startTests();
+    }
+
+    private void printval(ArrayReference backTraceVal, int index) throws Exception {
+        ArrayReference val = (ArrayReference)backTraceVal.getValue(index);
+        println("BT: val at " + index + " = " + val);
+
+        // The segv used to happen here for index = 0
+        // Now all objects in the backtrace are objects.
+        Object xVal = (Object)val.getValue(0);
+        println("BT: xVal = " + xVal);
+    }
+
+    /********** test core **********/
+
+    protected void runTests() throws Exception {
+        /*
+         * Get to the top of gus()
+         * to determine mainThread
+         */
+        BreakpointEvent bpe = startTo("BacktraceFieldTarg", "gus", "()V");
+        mainThread = bpe.thread();
+
+        /*
+         * We are now one frame below the exception frame that contains
+         * our ee var.
+         */
+        StackFrame myFrame = mainThread.frame(1);
+
+        LocalVariable lv = myFrame.visibleVariableByName("ee");
+        println("BT: lv = " + lv);
+        println("BT: lvType = " + lv.typeName());
+
+        List allFields = ((ReferenceType)(lv.type())).allFields();
+        println("BT: allFields = " + allFields);
+
+        /*
+         * Search through the fields of ee to verify that
+         * java.lang.Throwable.backtrace isn't there.
+         */
+        boolean backtrace_found = false;
+        Iterator iter = allFields.iterator();
+        while(iter.hasNext()) {
+            Field ff = (Field)iter.next();
+            if (ff.toString().equals("java.lang.Throwable.backtrace")) {
+                backtrace_found = true;
+                println("java.lang.Throwable.backtrace field not filtered out.");
+
+                /*
+                 * If you want to experience the segv this bug causes, change
+                 * this test to 1 == 1 and run it with jdk 1.4, build 74 or earlier
+                 */
+                if (1 == 1) {
+                    // The following code will show the segv that this can cause.
+                    ObjectReference myVal = (ObjectReference)myFrame.getValue(lv);
+                    println("BT: myVal = " + myVal);
+
+                    ArrayReference backTraceVal = (ArrayReference)myVal.getValue(ff);
+                    println("BT: backTraceVal = " + backTraceVal);
+
+                    printval(backTraceVal, 0);
+                    printval(backTraceVal, 1);
+                    printval(backTraceVal, 2);
+                    printval(backTraceVal, 3);  // backtrace has 4 elements
+
+                    try {
+                        printval(backTraceVal, 4);
+                    } catch (Exception e) {
+                        println("Exception " + e);
+                    }
+                }
+                break;
+            }
+        }
+
+        if (!backtrace_found) {
+            failure("ERROR: java.lang.Throwable.backtrace field filtered out.");
+        }
+
+        // Next, verify that we don't accidently discard a field that we shouldn't
+
+        if (!testFailed) {
+            lv = myFrame.visibleVariableByName("myTesty");
+
+            allFields = ((ReferenceType)(lv.type())).allFields();
+            println("BT: allFields = " + allFields);
+
+            if (allFields.size() != Testy.field7) {
+                failure("ERROR: wrong number of fields; expected " + Testy.field7 + ", Got " + allFields.size());
+            } else {
+                iter = allFields.iterator();
+                while(iter.hasNext()) {
+                    String fieldName = ((Field)iter.next()).toString();
+                    if (!fieldName.startsWith("Testy.field", 0)) {
+                        failure("ERROR: Found bogus field: " + fieldName.toString());
+                    }
+                }
+            }
+        }
+
+        listenUntilVMDisconnect();
+
+        /*
+         * deal with results of test
+         * if anything has called failure("foo") testFailed will be true
+         */
+        if (!testFailed) {
+            println("BacktraceFieldTest: passed");
+        } else {
+            throw new Exception("BacktraceFieldTest: failed");
+        }
+    }
+}