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 }