1 /*
   2  * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *  @test
  26  *  @bug 4446677
  27  *  @bug 8158237
  28  *  @summary debuggee used to crash when debugging under jbuilder
  29  *
  30  *  @author jjh
  31  *
  32  *  @modules jdk.jdi
  33  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
  34  *  @run compile -g BacktraceFieldTest.java
  35  *  @run driver BacktraceFieldTest
  36  */
  37 
  38 /*
  39  * The fix for this bug filters out the backtrace field from the list
  40  * of fields for java.lang.Throwable.
  41  * This test verifies that this really happens, and also verifies that the fix
  42  * doesn't incorrectly discard other fields.
  43  */
  44 
  45 import com.sun.jdi.*;
  46 import com.sun.jdi.event.*;
  47 import com.sun.jdi.request.*;
  48 
  49 import java.util.*;
  50 
  51 /********** target program **********/
  52 
  53 class Testy {
  54     /*
  55      * This is used to verify that the fix doesn't filter out fields that it
  56      * shouldn't.  7 is an abitrary number, and this isn't a definitive
  57      * test; the fix could conceivably filter out the 89th field of a class
  58      * named Foo.
  59      * To verify that this part of this test works, first uncomment the field8
  60      * line and verify that the test fails, and then rename a field to xxx and
  61      * verify that the test fails.
  62      */
  63     int field1;
  64     int field2;
  65     int field3;
  66     int field4;
  67     int field5;
  68     int field6;
  69     final static int field7 = 7;  // Value is the number of fields.
  70     //int field8;
  71 
  72     Testy() {
  73     }
  74 }
  75 
  76 
  77 class BacktraceFieldTarg {
  78     public static void gus() {
  79     }
  80 
  81     public static void main(String[] args) {
  82         Testy myTesty = new Testy();
  83         try {
  84             throw new RuntimeException("jjException");
  85         } catch (Exception ee) {
  86             gus();
  87             System.out.println("debuggee: Exception: " + ee);
  88         }
  89     }
  90 }
  91 
  92 /********** test program **********/
  93 
  94 public class BacktraceFieldTest extends TestScaffold {
  95     ThreadReference mainThread;
  96 
  97     BacktraceFieldTest (String args[]) {
  98         super(args);
  99     }
 100 
 101     public static void main(String[] args)      throws Exception {
 102         new BacktraceFieldTest(args).startTests();
 103     }
 104 
 105     private void printval(ArrayReference backTraceVal, int index) throws Exception {
 106         ArrayReference val = (ArrayReference)backTraceVal.getValue(index);
 107         println("BT: val at " + index + " = " + val);
 108 
 109         // The segv used to happen here for index = 0
 110         // Now all objects in the backtrace are objects.
 111         Object xVal = (Object)val.getValue(0);
 112         println("BT: xVal = " + xVal);
 113     }
 114 
 115     /********** test core **********/
 116 
 117     protected void runTests() throws Exception {
 118         /*
 119          * Get to the top of gus()
 120          * to determine mainThread
 121          */
 122         BreakpointEvent bpe = startTo("BacktraceFieldTarg", "gus", "()V");
 123         mainThread = bpe.thread();
 124 
 125         /*
 126          * We are now one frame below the exception frame that contains
 127          * our ee var.
 128          */
 129         StackFrame myFrame = mainThread.frame(1);
 130 
 131         LocalVariable lv = myFrame.visibleVariableByName("ee");
 132         println("BT: lv = " + lv);
 133         println("BT: lvType = " + lv.typeName());
 134 
 135         List allFields = ((ReferenceType)(lv.type())).allFields();
 136         println("BT: allFields = " + allFields);
 137 
 138         /*
 139          * Search through the fields of ee to verify that
 140          * java.lang.Throwable.backtrace isn't there.
 141          */
 142         boolean backtrace_found = false;
 143         Iterator iter = allFields.iterator();
 144         while(iter.hasNext()) {
 145             Field ff = (Field)iter.next();
 146             if (ff.toString().equals("java.lang.Throwable.backtrace")) {
 147                 backtrace_found = true;
 148                 println("java.lang.Throwable.backtrace field not filtered out.");
 149 
 150                 /*
 151                  * If you want to experience the segv this bug causes, change
 152                  * this test to 1 == 1 and run it with jdk 1.4, build 74 or earlier
 153                  */
 154                 if (1 == 1) {
 155                     // The following code will show the segv that this can cause.
 156                     ObjectReference myVal = (ObjectReference)myFrame.getValue(lv);
 157                     println("BT: myVal = " + myVal);
 158 
 159                     ArrayReference backTraceVal = (ArrayReference)myVal.getValue(ff);
 160                     println("BT: backTraceVal = " + backTraceVal);
 161 
 162                     printval(backTraceVal, 0);
 163                     printval(backTraceVal, 1);
 164                     printval(backTraceVal, 2);
 165                     printval(backTraceVal, 3);  // backtrace has 4 elements
 166 
 167                     try {
 168                         printval(backTraceVal, 4);
 169                     } catch (Exception e) {
 170                         println("Exception " + e);
 171                     }
 172                 }
 173                 break;
 174             }
 175         }
 176 
 177         if (!backtrace_found) {
 178             failure("ERROR: java.lang.Throwable.backtrace field filtered out.");
 179         }
 180 
 181         // Next, verify that we don't accidently discard a field that we shouldn't
 182 
 183         if (!testFailed) {
 184             lv = myFrame.visibleVariableByName("myTesty");
 185 
 186             allFields = ((ReferenceType)(lv.type())).allFields();
 187             println("BT: allFields = " + allFields);
 188 
 189             if (allFields.size() != Testy.field7) {
 190                 failure("ERROR: wrong number of fields; expected " + Testy.field7 + ", Got " + allFields.size());
 191             } else {
 192                 iter = allFields.iterator();
 193                 while(iter.hasNext()) {
 194                     String fieldName = ((Field)iter.next()).toString();
 195                     if (!fieldName.startsWith("Testy.field", 0)) {
 196                         failure("ERROR: Found bogus field: " + fieldName.toString());
 197                     }
 198                 }
 199             }
 200         }
 201 
 202         listenUntilVMDisconnect();
 203 
 204         /*
 205          * deal with results of test
 206          * if anything has called failure("foo") testFailed will be true
 207          */
 208         if (!testFailed) {
 209             println("BacktraceFieldTest: passed");
 210         } else {
 211             throw new Exception("BacktraceFieldTest: failed");
 212         }
 213     }
 214 }