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 }