1 19 20 package org.netbeans.modules.debugger.jpda.breakpoints; 21 22 import com.sun.jdi.Location; 23 import com.sun.jdi.Method; 24 import com.sun.jdi.ReferenceType; 25 import com.sun.jdi.VMDisconnectedException; 26 import com.sun.jdi.Value; 27 import com.sun.jdi.VirtualMachine; 28 import com.sun.jdi.event.BreakpointEvent; 29 import com.sun.jdi.event.Event; 30 import com.sun.jdi.event.LocatableEvent; 31 import com.sun.jdi.event.MethodEntryEvent; 32 import com.sun.jdi.event.MethodExitEvent; 33 import com.sun.jdi.request.BreakpointRequest; 34 import com.sun.jdi.request.MethodEntryRequest; 35 import com.sun.jdi.request.MethodExitRequest; 36 import java.util.ArrayList ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.Set ; 41 import org.netbeans.api.debugger.Breakpoint.VALIDITY; 42 import org.netbeans.api.debugger.Session; 43 import org.netbeans.api.debugger.jpda.ClassLoadUnloadBreakpoint; 44 import org.netbeans.api.debugger.jpda.MethodBreakpoint; 45 import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; 46 import org.openide.util.NbBundle; 47 48 53 public class MethodBreakpointImpl extends ClassBasedBreakpoint { 54 55 private static final boolean IS_JDK_16 = !System.getProperty("java.version").startsWith("1.5"); 57 58 private MethodBreakpoint breakpoint; 59 60 61 public MethodBreakpointImpl (MethodBreakpoint breakpoint, JPDADebuggerImpl debugger, Session session) { 62 super (breakpoint, debugger, session); 63 this.breakpoint = breakpoint; 64 set (); 65 } 66 67 public static boolean canGetMethodReturnValues(VirtualMachine vm) { 68 if (!IS_JDK_16) return false; 69 boolean canGetMethodReturnValues = false; 70 java.lang.reflect.Method m = null; 71 try { 72 m = vm.getClass().getMethod("canGetMethodReturnValues", new Class [] {}); 73 } catch (Exception ex) { 74 } 75 if (m != null) { 76 try { 77 m.setAccessible(true); 78 Object ret = m.invoke(vm, new Object [] {}); 79 canGetMethodReturnValues = Boolean.TRUE.equals(ret); 80 } catch (Exception ex) { 81 } 82 } 83 return canGetMethodReturnValues; 84 } 85 86 protected void setRequests () { 87 setClassRequests ( 88 breakpoint.getClassFilters (), 89 breakpoint.getClassExclusionFilters (), 90 ClassLoadUnloadBreakpoint.TYPE_CLASS_LOADED 91 ); 92 checkLoadedClasses (breakpoint.getClassFilters () [0]); 93 } 94 95 public boolean exec (Event event) { 96 if (event instanceof BreakpointEvent) 97 return perform ( 98 breakpoint.getCondition (), 99 ((BreakpointEvent) event).thread (), 100 ((LocatableEvent) event).location ().declaringType (), 101 null 102 ); 103 if (event instanceof MethodEntryEvent) { 104 String methodName = ((MethodEntryEvent) event).method().name(); 105 Set methodNames = (Set ) event.request().getProperty("methodNames"); 106 if (methodNames == null || methodNames.contains(methodName)) { 107 ReferenceType refType = null; 108 if (((LocatableEvent) event).location() != null) { 109 refType = ((LocatableEvent) event).location().declaringType(); 110 } 111 return perform ( 112 breakpoint.getCondition (), 113 ((MethodEntryEvent) event).thread (), 114 refType, 115 null 116 ); 117 } 118 } 119 if (event instanceof MethodExitEvent) { 120 String methodName = ((MethodExitEvent) event).method().name(); 121 Set methodNames = (Set ) event.request().getProperty("methodNames"); 122 if (methodNames == null || methodNames.contains(methodName)) { 123 ReferenceType refType = null; 124 if (((LocatableEvent) event).location() != null) { 125 refType = ((LocatableEvent) event).location().declaringType(); 126 } 127 Value returnValue = null; 128 129 if (IS_JDK_16) { VirtualMachine vm = event.virtualMachine(); 131 if (canGetMethodReturnValues(vm)) { 133 java.lang.reflect.Method m = null; 135 try { 136 m = event.getClass().getDeclaredMethod("returnValue", new Class [] {}); 137 } catch (Exception ex) { 138 m = null; 139 } 140 if (m != null) { 141 try { 142 m.setAccessible(true); 143 Object ret = m.invoke(event, new Object [] {}); 144 returnValue = (Value) ret; 145 } catch (Exception ex) { 146 } 147 } 148 } 149 } 150 return perform ( 151 breakpoint.getCondition (), 152 ((MethodExitEvent) event).thread (), 153 refType, 154 returnValue 155 ); 156 } 157 } 158 return super.exec (event); 159 } 160 161 protected void classLoaded (ReferenceType referenceType) { 162 Iterator methods = referenceType.methods ().iterator (); 163 MethodEntryRequest entryReq = null; 164 MethodExitRequest exitReq = null; 165 Set <String > entryMethodNames = null; 166 Set <String > exitMethodNames = null; 167 boolean locationEntry = false; 168 String methodName = breakpoint.getMethodName(); 169 while (methods.hasNext ()) { 170 Method method = (Method) methods.next (); 171 if (methodName.equals("") || match (method.name (), methodName)) { 172 173 if ((breakpoint.getBreakpointType() & breakpoint.TYPE_METHOD_ENTRY) != 0) { 174 if (method.location () != null && !method.isNative()) { 175 Location location = method.location (); 176 try { 177 BreakpointRequest br = getEventRequestManager (). 178 createBreakpointRequest (location); 179 addEventRequest (br); 180 } catch (VMDisconnectedException e) { 181 } 182 locationEntry = true; 183 } else { 184 if (entryReq == null) { 185 entryReq = getEventRequestManager(). 186 createMethodEntryRequest(); 187 entryReq.addClassFilter(referenceType); 188 entryMethodNames = new HashSet <String >(); 189 entryReq.putProperty("methodNames", entryMethodNames); 190 } 191 entryMethodNames.add(method.name ()); 192 } 193 } 194 if ((breakpoint.getBreakpointType() & breakpoint.TYPE_METHOD_EXIT) != 0) { 195 if (exitReq == null) { 196 exitReq = getEventRequestManager(). 197 createMethodExitRequest(); 198 exitReq.addClassFilter(referenceType); 199 exitMethodNames = new HashSet <String >(); 200 exitReq.putProperty("methodNames", exitMethodNames); 201 } 202 exitMethodNames.add(method.name()); 203 } 204 } 205 } 206 if (entryReq != null) { 207 addEventRequest(entryReq); 208 } 209 if (exitReq != null) { 210 addEventRequest(exitReq); 211 } 212 if (locationEntry || entryReq != null || exitReq != null) { 213 setValidity(VALIDITY.VALID, null); 214 } else { 215 setValidity(VALIDITY.INVALID, 216 NbBundle.getMessage(MethodBreakpointImpl.class, "MSG_NoMethod", referenceType.name(), methodName)); 217 } 218 } 219 } 220 221 | Popular Tags |