1 /* 2 * Copyright (c) 2000, 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 4312961 27 * @summary Verify that an instance filter on a MethodEntryRequest works 28 * properly. 29 * @author Robert Field/Jim Holmlund 30 * 31 * @run build TestScaffold VMConnection TargetAdapter TargetListener 32 * @run compile -g InstanceFilter.java 33 * @run driver InstanceFilter 34 */ 35 import com.sun.jdi.*; 36 import com.sun.jdi.event.*; 37 import com.sun.jdi.request.*; 38 39 class InstanceFilterTarg { 40 static InstanceFilterTarg first = new InstanceFilterTarg(); 41 static InstanceFilterTarg second = new InstanceFilterTarg(); 42 static InstanceFilterTarg third = new InstanceFilterTarg(); 43 44 public static void main(String args[]) { 45 start(); 46 } 47 48 static void start() { 49 first.go(); 50 second.go(); 51 third.go(); 52 } 53 54 void go() { 55 one(); 56 two(); 57 three(); 58 } 59 60 void one() { 61 } 62 63 void two() { 64 } 65 66 void three() { 67 } 68 } 69 70 public class InstanceFilter extends TestScaffold { 71 ReferenceType targetClass; 72 73 ObjectReference theInstance; 74 MethodEntryRequest methodEntryRequest; 75 int methodCount = 0; 76 // These are the methods for which we expect to get MethodEntryEvents. 77 String[] expectedMethods = new String[] { "go", "one", "two", "three"}; 78 79 public static void main(String args[]) throws Exception { 80 new InstanceFilter(args).startTests(); 81 } 82 83 InstanceFilter(String args[]) throws Exception { 84 super(args); 85 } 86 87 /** 88 * Override TestScaffold.methodEntered. This should get called 89 * once for each method named in 'expectedMethods', and for 90 * the instance that we select to filter on. 91 */ 92 public void methodEntered(MethodEntryEvent event) { 93 if (testFailed) { 94 return; 95 } 96 // Find the instance and verify that it is 97 // the one we want. 98 ObjectReference theThis; 99 try { 100 theThis = event.thread().frame(0).thisObject(); 101 } catch (IncompatibleThreadStateException ee) { 102 failure("FAILED: Exception occured in methodEntered: " + ee); 103 return; 104 } 105 if (theThis == null) { 106 // This happens when the thread has exited or when a 107 // static method is called. Setting an instance 108 // filter does not prevent this event from being 109 // emitted with a this that is null. 110 methodEntryRequest.disable(); 111 return; 112 } 113 114 if (!theThis.equals(theInstance)) { 115 failure("FAILED: Got a hit on a non-selected instance"); 116 } 117 118 // fail if we don't get called for each of the expected methods 119 { 120 String methodStr = event.location().method().name(); 121 122 if (methodCount >= expectedMethods.length) { 123 failure("FAILED: Got too many methodEntryEvents"); 124 } else if (methodStr.indexOf(expectedMethods[methodCount]) == -1) { 125 failure("FAILED: Expected method: " + expectedMethods[methodCount]); 126 } 127 methodCount++; 128 println("Method: " + methodStr); 129 } 130 } 131 132 protected void runTests() throws Exception { 133 134 BreakpointEvent bpe = startTo("InstanceFilterTarg", "go", "()V"); 135 targetClass = bpe.location().declaringType(); 136 137 Field field = targetClass.fieldByName("second"); 138 theInstance = (ObjectReference)(targetClass.getValue(field)); 139 140 EventRequestManager mgr = vm().eventRequestManager(); 141 methodEntryRequest = mgr.createMethodEntryRequest(); 142 methodEntryRequest.addInstanceFilter(theInstance); 143 // Thread filter is needed to prevent MethodEntry events 144 // to be emitted by the debugee when a static method 145 // is called on any thread. 146 methodEntryRequest.addThreadFilter(bpe.thread()); 147 methodEntryRequest.enable(); 148 149 listenUntilVMDisconnect(); 150 151 if (!testFailed && methodCount < expectedMethods.length) { 152 failure("FAILED: Expected " + expectedMethods.length + " events, only got " 153 + methodCount); 154 } 155 if (!testFailed) { 156 println("InstanceFilter: passed"); 157 } else { 158 throw new Exception("InstanceFilter: failed"); 159 } 160 } 161 }