--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/FinalizerTest.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1999-2001 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 4272800 4274208 4392010
+ * @summary Test debugger operations in finalize() methods
+ * @author Gordon Hirsch (modified for HotSpot by tbell & rfield)
+ *
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter
+ * @run compile -g FinalizerTest.java
+ *
+ * @run main FinalizerTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/*
+ * Debuggee which exercises a finalize() method. There's no guarantee
+ * that this will work, but we need some way of attempting to test
+ * the debugging of finalizers.
+ * @author Gordon Hirsch (modified for HotSpot by tbell & rfield)
+ */
+class FinalizerTarg {
+ static String lockit = "lock";
+ static boolean finalizerRun = false;
+ static class BigObject {
+ String name;
+ byte[] foo = new byte[300000];
+
+ public BigObject (String _name) {
+ super();
+ this.name = _name;
+ }
+
+ protected void finalize() throws Throwable {
+ /*
+ * JLS 2nd Ed. section 12.6 "Finalization of Class Instances" "[...]
+ * invoke the finalize method for its superclass, [...] usually good
+ * practice [...]"
+ */
+ super.finalize();
+ //Thread.dumpStack();
+ finalizerRun = true;
+ }
+ }
+
+ static void waitForAFinalizer() {
+ String s = Integer.toString(1);
+ BigObject b = new BigObject (s);
+ b = null; // Drop the object, creating garbage...
+ System.gc();
+ System.runFinalization();
+
+ // Now, we have to make sure the finalizer
+ // gets run. We will keep allocating more
+ // and more memory with the idea that eventually,
+ // the memory occupied by the BigObject will get reclaimed
+ // and the finalizer will be run.
+ List holdAlot = new ArrayList();
+ for (int chunk=10000000; chunk > 10000; chunk = chunk / 2) {
+ if (finalizerRun) {
+ return;
+ }
+ try {
+ while(true) {
+ holdAlot.add(new byte[chunk]);
+ System.err.println("Allocated " + chunk);
+ }
+ }
+ catch ( Throwable thrown ) { // OutOfMemoryError
+ System.gc();
+ }
+ System.runFinalization();
+ }
+ return; // not reached
+ }
+
+ public static void main(String[] args) throws Exception {
+ /*
+ * Spin in waitForAFinalizer() while waiting for
+ * another thread to run the finalizer on one of the
+ * BigObjects ...
+ */
+ waitForAFinalizer();
+ }
+}
+///// End of debuggee
+
+
+public class FinalizerTest extends TestScaffold {
+
+ public static void main(String args[])
+ throws Exception {
+ new FinalizerTest (args).startTests();
+ }
+
+ public FinalizerTest (String args[]) {
+ super(args);
+ }
+
+ protected void runTests() throws Exception {
+ try {
+ BreakpointEvent event0 = startToMain("FinalizerTarg");
+
+ BreakpointEvent event1 = resumeTo("FinalizerTarg$BigObject",
+ "finalize", "()V");
+
+ println("Breakpoint at " +
+ event1.location().method().name() + ":" +
+ event1.location().lineNumber() + " (" +
+ event1.location().codeIndex() + ")");
+
+ /*
+ * Record information about the current location
+ */
+ List frames = event1.thread().frames();
+ List methodStack = new ArrayList(frames.size());
+ Iterator iter = frames.iterator();
+ while (iter.hasNext()) {
+ StackFrame frame = (StackFrame) iter.next();
+ methodStack.add(frame.location().declaringType().name() +
+ "." + frame.location().method().name());
+ }
+ println("Try a stepOverLine()...");
+ StepEvent stepEvent = stepOverLine(event1.thread());
+
+ println("Step Complete at " +
+ stepEvent.location().method().name() + ":" +
+ stepEvent.location().lineNumber() + " (" +
+ stepEvent.location().codeIndex() + ")");
+
+ /*
+ * Compare current location with recorded location
+ */
+ if (stepEvent.thread().frameCount() != methodStack.size()) {
+ throw new Exception("Stack depths do not match: original=" +
+ methodStack.size() +
+ ", current=" +
+ stepEvent.thread().frameCount());
+ }
+ iter = stepEvent.thread().frames().iterator();
+ Iterator iter2 = methodStack.iterator();
+ while (iter.hasNext()) {
+ StackFrame frame = (StackFrame) iter.next();
+ String name = (String) iter2.next();
+ String currentName = frame.location().declaringType().name() +
+ "." + frame.location().method().name();
+ if (!name.equals(currentName)) {
+ throw new Exception("Stacks do not match at: original=" +
+ name + ", current=" + currentName);
+
+ }
+ }
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ testFailed = true;
+ } finally {
+ // Allow application to complete and shut down
+ listenUntilVMDisconnect();
+ }
+ if (!testFailed) {
+ println("FinalizerTest: passed");
+ } else {
+ throw new Exception("FinalizerTest: failed");
+ }
+ }
+}