jdk/test/com/sun/jdi/FinalizerTest.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /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");
+        }
+    }
+}