1 /* 2 * Copyright (c) 1999, 2015, 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 4272800 4274208 4392010 27 * @summary Test debugger operations in finalize() methods 28 * @author Gordon Hirsch (modified for HotSpot by tbell & rfield) 29 * 30 * @modules jdk.jdi 31 * @run build TestScaffold VMConnection TargetListener TargetAdapter 32 * @run compile -g FinalizerTest.java 33 * 34 * @run driver FinalizerTest 35 */ 36 import com.sun.jdi.*; 37 import com.sun.jdi.event.*; 38 import com.sun.jdi.request.*; 39 40 import java.util.List; 41 import java.util.ArrayList; 42 import java.util.Iterator; 43 44 45 /* 46 * Debuggee which exercises a finalize() method. There's no guarantee 47 * that this will work, but we need some way of attempting to test 48 * the debugging of finalizers. 49 * @author Gordon Hirsch (modified for HotSpot by tbell & rfield) 50 */ 51 class FinalizerTarg { 52 static String lockit = "lock"; 53 static boolean finalizerRun = false; 54 static class BigObject { 55 String name; 56 byte[] foo = new byte[300000]; 57 58 public BigObject (String _name) { 59 super(); 60 this.name = _name; 61 } 62 63 protected void finalize() throws Throwable { 64 /* 65 * JLS 2nd Ed. section 12.6 "Finalization of Class Instances" "[...] 66 * invoke the finalize method for its superclass, [...] usually good 67 * practice [...]" 68 */ 69 super.finalize(); 70 //Thread.dumpStack(); 71 finalizerRun = true; 72 } 73 } 74 75 static void waitForAFinalizer() { 76 String s = Integer.toString(1); 77 BigObject b = new BigObject (s); 78 b = null; // Drop the object, creating garbage... 79 System.gc(); 80 System.runFinalization(); 81 82 // Now, we have to make sure the finalizer 83 // gets run. We will keep allocating more 84 // and more memory with the idea that eventually, 85 // the memory occupied by the BigObject will get reclaimed 86 // and the finalizer will be run. 87 List holdAlot = new ArrayList(); 88 for (int chunk=10000000; chunk > 10000; chunk = chunk / 2) { 89 if (finalizerRun) { 90 return; 91 } 92 try { 93 while(true) { 94 holdAlot.add(new byte[chunk]); 95 System.err.println("Allocated " + chunk); 96 } 97 } 98 catch ( Throwable thrown ) { // OutOfMemoryError 99 System.gc(); 100 } 101 System.runFinalization(); 102 } 103 return; // not reached 104 } 105 106 public static void main(String[] args) throws Exception { 107 /* 108 * Spin in waitForAFinalizer() while waiting for 109 * another thread to run the finalizer on one of the 110 * BigObjects ... 111 */ 112 waitForAFinalizer(); 113 } 114 } 115 ///// End of debuggee 116 117 118 public class FinalizerTest extends TestScaffold { 119 120 public static void main(String args[]) 121 throws Exception { 122 new FinalizerTest (args).startTests(); 123 } 124 125 public FinalizerTest (String args[]) { 126 super(args); 127 } 128 129 protected void runTests() throws Exception { 130 try { 131 BreakpointEvent event0 = startToMain("FinalizerTarg"); 132 133 BreakpointEvent event1 = resumeTo("FinalizerTarg$BigObject", 134 "finalize", "()V"); 135 136 println("Breakpoint at " + 137 event1.location().method().name() + ":" + 138 event1.location().lineNumber() + " (" + 139 event1.location().codeIndex() + ")"); 140 141 /* 142 * Record information about the current location 143 */ 144 List frames = event1.thread().frames(); 145 List methodStack = new ArrayList(frames.size()); 146 Iterator iter = frames.iterator(); 147 while (iter.hasNext()) { 148 StackFrame frame = (StackFrame) iter.next(); 149 methodStack.add(frame.location().declaringType().name() + 150 "." + frame.location().method().name()); 151 } 152 println("Try a stepOverLine()..."); 153 StepEvent stepEvent = stepOverLine(event1.thread()); 154 155 println("Step Complete at " + 156 stepEvent.location().method().name() + ":" + 157 stepEvent.location().lineNumber() + " (" + 158 stepEvent.location().codeIndex() + ")"); 159 160 /* 161 * Compare current location with recorded location 162 */ 163 if (stepEvent.thread().frameCount() != methodStack.size()) { 164 throw new Exception("Stack depths do not match: original=" + 165 methodStack.size() + 166 ", current=" + 167 stepEvent.thread().frameCount()); 168 } 169 iter = stepEvent.thread().frames().iterator(); 170 Iterator iter2 = methodStack.iterator(); 171 while (iter.hasNext()) { 172 StackFrame frame = (StackFrame) iter.next(); 173 String name = (String) iter2.next(); 174 String currentName = frame.location().declaringType().name() + 175 "." + frame.location().method().name(); 176 if (!name.equals(currentName)) { 177 throw new Exception("Stacks do not match at: original=" + 178 name + ", current=" + currentName); 179 180 } 181 } 182 } catch(Exception ex) { 183 ex.printStackTrace(); 184 testFailed = true; 185 } finally { 186 // Allow application to complete and shut down 187 listenUntilVMDisconnect(); 188 } 189 if (!testFailed) { 190 println("FinalizerTest: passed"); 191 } else { 192 throw new Exception("FinalizerTest: failed"); 193 } 194 } 195 }