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