@SuppressWarnings("unused") // called via reflection private void test1() throws Exception { System.out.println("DEBUG: ------------> Running test1"); try { Field field = targetClass.fieldByName("fooCls"); ClassType clsType = (ClassType)field.type(); Method constructor = getConstructorForClass(clsType); for (int i = 0; i < 15; i++) { @SuppressWarnings({ "rawtypes", "unchecked" }) ObjectReference objRef = clsType.newInstance(mainThread, constructor, new ArrayList(0), ObjectReference.INVOKE_NONVIRTUAL); if (objRef.isCollected()) { System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP."); continue; } invoke("testMethod", "(LOomDebugTestTarget$FooCls;)V", objRef); } } catch (InvocationException e) { handleFailure(e); } }
/** * Shared implementation of {@linkplain ClassType#allMethods()} and * {@linkplain InterfaceType#allMethods()} * @return A list of all methods (recursively) */ public final List<Method> allMethods() { ArrayList<Method> list = new ArrayList<>(methods()); ClassType clazz = superclass(); while (clazz != null) { list.addAll(clazz.methods()); clazz = clazz.superclass(); } /* * Avoid duplicate checking on each method by iterating through * duplicate-free allInterfaces() rather than recursing */ for (InterfaceType interfaze : getAllInterfaces()) { list.addAll(interfaze.methods()); } return list; }
private boolean ungrabWindowAWT(ThreadReference tr, ObjectReference grabbedWindow) { // Call XBaseWindow.ungrabInput() try { VirtualMachine vm = MirrorWrapper.virtualMachine(grabbedWindow); List<ReferenceType> xbaseWindowClassesByName = VirtualMachineWrapper.classesByName(vm, "sun.awt.X11.XBaseWindow"); if (xbaseWindowClassesByName.isEmpty()) { logger.info("Unable to release X grab, no XBaseWindow class in target VM "+VirtualMachineWrapper.description(vm)); return false; } ClassType XBaseWindowClass = (ClassType) xbaseWindowClassesByName.get(0); Method ungrabInput = XBaseWindowClass.concreteMethodByName("ungrabInput", "()V"); if (ungrabInput == null) { logger.info("Unable to release X grab, method ungrabInput not found in target VM "+VirtualMachineWrapper.description(vm)); return false; } XBaseWindowClass.invokeMethod(tr, ungrabInput, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); } catch (VMDisconnectedExceptionWrapper vmdex) { return true; // Disconnected, all is good. } catch (Exception ex) { logger.log(Level.INFO, "Unable to release X grab.", ex); return false; } return true; }
/** * Test whether the method is considered to be synthetic * @param m The method * @param loc The current location in that method * @return 0 when not synthetic * positive when suggested step depth is returned * negative when is synthetic and no further step depth is suggested. */ public static int isSyntheticMethod(Method m, Location loc) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper { String name = TypeComponentWrapper.name(m); if (name.startsWith("lambda$")) { // NOI18N int lineNumber = LocationWrapper.lineNumber(loc); if (lineNumber == 1) { // We're in the initialization of the Lambda. We need to step over it. return StepRequest.STEP_OVER; } return 0; // Do not treat Lambda methods as synthetic, because they contain user code. } else { // Do check the class for being Lambda synthetic class: ReferenceType declaringType = LocationWrapper.declaringType(loc); try { String className = ReferenceTypeWrapper.name(declaringType); if (className.contains("$$Lambda$")) { // NOI18N // Lambda synthetic class return -1; } } catch (ObjectCollectedExceptionWrapper ex) { } } return TypeComponentWrapper.isSynthetic(m) ? -1 : 0; }
private static Method getConcreteMethod(ReferenceType type, String methodName, String firstParamSignature, List<? extends TypeMirror> typeArguments) throws UnsuitableArgumentsException { List<Method> methods = type.methodsByName(methodName); String signature = createSignature(firstParamSignature, typeArguments); boolean constructor = "<init>".equals(methodName); for (Method method : methods) { if (!method.isAbstract() && (!constructor || type.equals(method.declaringType())) && equalMethodSignatures(method.signature(), signature)) { return method; } } if (methods.size() > 0) { throw new UnsuitableArgumentsException(); } return null; }
@Override final void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) { /* * Add methods from * parent types first, so that the methods in this class will * overwrite them in the hash table */ Iterator<InterfaceType> iter = interfaces().iterator(); while (iter.hasNext()) { InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next(); if (!seenInterfaces.contains(interfaze)) { interfaze.addVisibleMethods(methodMap, seenInterfaces); seenInterfaces.add(interfaze); } } ClassTypeImpl clazz = (ClassTypeImpl) superclass(); if (clazz != null) { clazz.addVisibleMethods(methodMap, seenInterfaces); } addToMethodMap(methodMap, methods()); }
LocalVariableImpl(VirtualMachine vm, Method method, int slot, Location scopeStart, Location scopeEnd, String name, String signature, String genericSignature) { super(vm); this.method = method; this.slot = slot; this.scopeStart = scopeStart; this.scopeEnd = scopeEnd; this.name = name; this.signature = signature; if (genericSignature != null && genericSignature.length() > 0) { this.genericSignature = genericSignature; } else { // The Spec says to return null for non-generic types this.genericSignature = null; } }
public boolean isVisible(StackFrame frame) { validateMirror(frame); Method frameMethod = frame.location().method(); if (!frameMethod.equals(method)) { throw new IllegalArgumentException( "frame method different than variable's method"); } // this is here to cover the possibility that we will // allow LocalVariables for native methods. If we do // so we will have to re-examinine this. if (frameMethod.isNative()) { return false; } return ((scopeStart.compareTo(frame.location()) <= 0) && (scopeEnd.compareTo(frame.location()) >= 0)); }
Method getMethodMirror(long ref) { if (ref == 0) { // obsolete method return new ObsoleteMethodImpl(vm, this); } // Fetch all methods for the class, check performance impact // Needs no synchronization now, since methods() returns // unmodifiable local data Iterator<Method> it = methods().iterator(); while (it.hasNext()) { MethodImpl method = (MethodImpl)it.next(); if (method.ref() == ref) { return method; } } throw new IllegalArgumentException("Invalid method id: " + ref); }
private List<Method> methods1_4() { List<Method> methods; JDWP.ReferenceType.Methods.MethodInfo[] declared; try { declared = JDWP.ReferenceType.Methods. process(vm, this).declared; } catch (JDWPException exc) { throw exc.toJDIException(); } methods = new ArrayList<Method>(declared.length); for (int i=0; i<declared.length; i++) { JDWP.ReferenceType.Methods.MethodInfo mi = declared[i]; Method method = MethodImpl.createMethodImpl(vm, this, mi.methodID, mi.name, mi.signature, null, mi.modBits); methods.add(method); } return methods; }
public List<Method> visibleMethods() { /* * Build a collection of all visible methods. The hash * map allows us to do this efficiently by keying on the * concatenation of name and signature. */ Map<String, Method> map = new HashMap<String, Method>(); addVisibleMethods(map, new HashSet<InterfaceType>()); /* * ... but the hash map destroys order. Methods should be * returned in a sensible order, as they are in allMethods(). * So, start over with allMethods() and use the hash map * to filter that ordered collection. */ List<Method> list = allMethods(); list.retainAll(new HashSet<Method>(map.values())); return list; }
public List<Location> allLineLocations(String stratumID, String sourceName) throws AbsentInformationException { boolean someAbsent = false; // A method that should have info, didn't SDE.Stratum stratum = stratum(stratumID); List<Location> list = new ArrayList<Location>(); // location list for (Iterator<Method> iter = methods().iterator(); iter.hasNext(); ) { MethodImpl method = (MethodImpl)iter.next(); try { list.addAll( method.allLineLocations(stratum, sourceName)); } catch(AbsentInformationException exc) { someAbsent = true; } } // If we retrieved no line info, and at least one of the methods // should have had some (as determined by an // AbsentInformationException being thrown) then we rethrow // the AbsentInformationException. if (someAbsent && list.size() == 0) { throw new AbsentInformationException(); } return list; }
void validateMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * Method must be in this object's class, a superclass, or * implemented interface */ ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); if (!declType.isAssignableFrom(this)) { throw new IllegalArgumentException("Invalid method"); } if (declType instanceof ClassTypeImpl) { validateClassMethodInvocation(method, options); } else if (declType instanceof InterfaceTypeImpl) { validateIfaceMethodInvocation(method, options); } else { throw new InvalidTypeException(); } }
void validateClassMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * Method must be a non-constructor */ if (method.isConstructor()) { throw new IllegalArgumentException("Cannot invoke constructor"); } /* * For nonvirtual invokes, method must have a body */ if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } } }
void validateConstructorInvocation(Method method) throws InvalidTypeException, InvocationException { /* * Method must be in this class. */ ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); if (!declType.equals(this)) { throw new IllegalArgumentException("Invalid constructor"); } /* * Method must be a constructor */ if (!method.isConstructor()) { throw new IllegalArgumentException("Cannot create instance with non-constructor"); } }
/** * Check if the current top stack is same as the original top stack. * * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ private boolean shouldDoExtraStepInto(int originalStackDepth, Location originalLocation, int currentStackDepth, Location currentLocation) throws IncompatibleThreadStateException { if (originalStackDepth != currentStackDepth) { return false; } if (originalLocation == null) { return false; } Method originalMethod = originalLocation.method(); Method currentMethod = currentLocation.method(); if (!originalMethod.equals(currentMethod)) { return false; } if (originalLocation.lineNumber() != currentLocation.lineNumber()) { return false; } return true; }
private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context) throws URISyntaxException, AbsentInformationException { Location location = stackFrame.location(); Method method = location.method(); Types.Source clientSource = this.convertDebuggerSourceToClient(location, context); String methodName = formatMethodName(method, true, true); int lineNumber = AdapterUtils.convertLineNumber(location.lineNumber(), context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); // Line number returns -1 if the information is not available; specifically, always returns -1 for native methods. if (lineNumber < 0) { if (method.isNative()) { // For native method, display a tip text "native method" in the Call Stack View. methodName += "[native method]"; } else { // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, // display "Unknown Source" in the Call Stack View. clientSource = null; } } return new Types.StackFrame(frameId, methodName, clientSource, lineNumber, 0); }
private String formatMethodName(Method method, boolean showContextClass, boolean showParameter) { StringBuilder formattedName = new StringBuilder(); if (showContextClass) { String fullyQualifiedClassName = method.declaringType().name(); formattedName.append(SimpleTypeFormatter.trimTypeName(fullyQualifiedClassName)); formattedName.append("."); } formattedName.append(method.name()); if (showParameter) { List<String> argumentTypeNames = method.argumentTypeNames().stream().map(SimpleTypeFormatter::trimTypeName).collect(Collectors.toList()); formattedName.append("("); formattedName.append(String.join(",", argumentTypeNames)); formattedName.append(")"); } return formattedName.toString(); }
/** * Suspend the main thread when the program enters the main method of the specified main class. * @param debugSession * the debug session. * @param mainClass * the fully qualified name of the main class. * @return * a {@link CompletableFuture} that contains the suspended main thread id. */ public static CompletableFuture<Long> stopOnEntry(IDebugSession debugSession, String mainClass) { CompletableFuture<Long> future = new CompletableFuture<>(); EventRequestManager manager = debugSession.getVM().eventRequestManager(); MethodEntryRequest request = manager.createMethodEntryRequest(); request.addClassFilter(mainClass); request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); debugSession.getEventHub().events().filter(debugEvent -> { return debugEvent.event instanceof MethodEntryEvent && request.equals(debugEvent.event.request()); }).subscribe(debugEvent -> { Method method = ((MethodEntryEvent) debugEvent.event).method(); if (method.isPublic() && method.isStatic() && method.name().equals("main") && method.signature().equals("([Ljava/lang/String;)V")) { deleteEventRequestSafely(debugSession.getVM().eventRequestManager(), request); debugEvent.shouldResume = false; ThreadReference bpThread = ((MethodEntryEvent) debugEvent.event).thread(); future.complete(bpThread.uniqueID()); } }); request.enable(); return future; }
@Override public void perform(String[] argv, Context ctx) { EventRequestManager manager = ctx.getVm().eventRequestManager(); MethodEntryRequest mer = manager.createMethodEntryRequest(); mer.setSuspendPolicy(EventRequest.SUSPEND_NONE); mer.enable(); ctx.register(mer, new EventCallback() { @Override public void handleEvent(Event event) { MethodEntryEvent mee = (MethodEntryEvent) event; Method method = mee.method(); System.out.println("--" + method.name()); // mee.thread().resume(); } }); }
@Override void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) { /* * Add methods from * parent types first, so that the methods in this class will * overwrite them in the hash table */ Iterator<InterfaceType> iter = superinterfaces().iterator(); while (iter.hasNext()) { InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); if (!seenInterfaces.contains(interfaze)) { interfaze.addVisibleMethods(methodMap, seenInterfaces); seenInterfaces.add(interfaze); } } addToMethodMap(methodMap, methods()); }
public Method concreteMethodByName(String name, String signature) { checkPrepared(); List methods = visibleMethods(); Method method = null; Iterator iter = methods.iterator(); while (iter.hasNext()) { Method candidate = (Method)iter.next(); if (candidate.name().equals(name) && candidate.signature().equals(signature) && !candidate.isAbstract()) { method = candidate; break; } } return method; }
@Override void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) { /* * Add methods from * parent types first, so that the methods in this class will * overwrite them in the hash table */ Iterator<InterfaceType> iter = interfaces().iterator(); while (iter.hasNext()) { InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); if (!seenInterfaces.contains(interfaze)) { interfaze.addVisibleMethods(methodMap, seenInterfaces); seenInterfaces.add(interfaze); } } ClassTypeImpl clazz = (ClassTypeImpl)superclass(); if (clazz != null) { clazz.addVisibleMethods(methodMap, seenInterfaces); } addToMethodMap(methodMap, methods()); }
@Nullable public static String getContextKeyForFrame(final StackFrameProxyImpl frame) { if (frame == null) { return null; } try { final Location location = frame.location(); final Method method = location.method(); final ReferenceType referenceType = location.declaringType(); final StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { return builder.append(referenceType.signature()).append("#").append(method.name()).append(method.signature()).toString(); } finally { StringBuilderSpinAllocator.dispose(builder); } } catch (EvaluateException e) { return null; } }