@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); } }
/** * Auto-boxes or un-boxes arguments of a method. */ static void autoboxArguments(List<Type> types, List<Value> argVals, ThreadReference evaluationThread, EvaluationContext evaluationContext) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { if (types.size() != argVals.size()) { return ; } int n = types.size(); for (int i = 0; i < n; i++) { Type t = types.get(i); Value v = argVals.get(i); if (v instanceof ObjectReference && t instanceof PrimitiveType) { argVals.set(i, unbox((ObjectReference) v, (PrimitiveType) t, evaluationThread, evaluationContext)); } if (v instanceof PrimitiveValue && t instanceof ReferenceType) { argVals.set(i, box((PrimitiveValue) v, (ReferenceType) t, evaluationThread, evaluationContext)); } } }
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"); } }
/** * Gets the message of an exception. * Inspired by org.eclipse.jdt.internal.debug.ui.actions.EvaluateAction.getExceptionMessage. * @param exception The exception whose message we want to get. * @return The message of the given exception. */ public static String getExceptionMessage(Throwable exception) { if (exception instanceof CoreException) { CoreException ce = (CoreException)exception; Throwable throwable = ce.getStatus().getException(); if (throwable instanceof InvocationException) { ObjectReference ref = ((InvocationException)throwable).exception(); return "An exception occurred: " + ref.referenceType().name(); } else if (throwable instanceof CoreException) return getExceptionMessage(throwable); return ce.getStatus().getMessage(); } String message = "An exception occurred: " + exception.getClass(); if (exception.getMessage() != null) message += " - " + exception.getMessage(); return message; }
private static void pauseMedia(ThreadReference tr, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { final ClassType audioClipClass = getClass(vm, tr, "com.sun.media.jfxmedia.AudioClip"); final ClassType mediaManagerClass = getClass(vm, tr, "com.sun.media.jfxmedia.MediaManager"); final InterfaceType mediaPlayerClass = getInterface(vm, tr, "com.sun.media.jfxmedia.MediaPlayer"); final ClassType playerStateEnum = getClass(vm, tr, "com.sun.media.jfxmedia.events.PlayerStateEvent$PlayerState"); if (audioClipClass != null) { Method stopAllClips = audioClipClass.concreteMethodByName("stopAllClips", "()V"); audioClipClass.invokeMethod(tr, stopAllClips, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); } if (mediaManagerClass != null && mediaPlayerClass != null && playerStateEnum != null) { Method getAllPlayers = mediaManagerClass.concreteMethodByName("getAllMediaPlayers", "()Ljava/util/List;"); ObjectReference plList = (ObjectReference)mediaManagerClass.invokeMethod(tr, getAllPlayers, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); if (plList != null) { ClassType listType = (ClassType)plList.referenceType(); Method iterator = listType.concreteMethodByName("iterator", "()Ljava/util/Iterator;"); ObjectReference plIter = (ObjectReference)plList.invokeMethod(tr, iterator, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); ClassType iterType = (ClassType)plIter.referenceType(); Method hasNext = iterType.concreteMethodByName("hasNext", "()Z"); Method next = iterType.concreteMethodByName("next", "()Ljava/lang/Object;"); Field playingState = playerStateEnum.fieldByName("PLAYING"); Method getState = mediaPlayerClass.methodsByName("getState", "()Lcom/sun/media/jfxmedia/events/PlayerStateEvent$PlayerState;").get(0); Method pausePlayer = mediaPlayerClass.methodsByName("pause", "()V").get(0); boolean hasNextFlag = false; do { BooleanValue v = (BooleanValue)plIter.invokeMethod(tr, hasNext, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); hasNextFlag = v.booleanValue(); if (hasNextFlag) { ObjectReference player = (ObjectReference)plIter.invokeMethod(tr, next, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); ObjectReference curState = (ObjectReference)player.invokeMethod(tr, getState, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); if (playingState.equals(curState)) { player.invokeMethod(tr, pausePlayer, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); pausedPlayers.add(player); } } } while (hasNextFlag); } } }
private static void resumeMedia(ThreadReference tr, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { if (!pausedPlayers.isEmpty()) { final InterfaceType mediaPlayerClass = getInterface(vm, tr, "com.sun.media.jfxmedia.MediaPlayer"); List<Method> play = mediaPlayerClass.methodsByName("play", "()V"); if (play.isEmpty()) { return; } Method p = play.iterator().next(); for(ObjectReference pR : pausedPlayers) { pR.invokeMethod(tr, p, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); } } }
private static ReferenceType getType(VirtualMachine vm, ThreadReference tr, String name) { List<ReferenceType> classList = VirtualMachineWrapper.classesByName0(vm, name); if (!classList.isEmpty()) { return classList.iterator().next(); } List<ReferenceType> classClassList = VirtualMachineWrapper.classesByName0(vm, "java.lang.Class"); // NOI18N if (classClassList.isEmpty()) { throw new IllegalStateException("Cannot load class Class"); // NOI18N } ClassType cls = (ClassType) classClassList.iterator().next(); try { Method m = ClassTypeWrapper.concreteMethodByName(cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); // NOI18N StringReference mirrorOfName = VirtualMachineWrapper.mirrorOf(vm, name); ClassTypeWrapper.invokeMethod(cls, tr, m, Collections.singletonList(mirrorOfName), ObjectReference.INVOKE_SINGLE_THREADED); List<ReferenceType> classList2 = VirtualMachineWrapper.classesByName0(vm, name); if (!classList2.isEmpty()) { return classList2.iterator().next(); } } catch (ClassNotLoadedException | ClassNotPreparedExceptionWrapper | IncompatibleThreadStateException | InvalidTypeException | InvocationException | InternalExceptionWrapper | ObjectCollectedExceptionWrapper | UnsupportedOperationExceptionWrapper | VMDisconnectedExceptionWrapper ex) { logger.log(Level.FINE, "Cannot load class " + name, ex); // NOI18N } return null; }
private static void setValueToFinalField(ObjectReference obj, String name, ClassType clazz, Value fv, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException, InvalidObjectException { ObjectReference fieldRef = getDeclaredOrInheritedField(clazz, name, vm, thread); if (fieldRef == null) { InvalidObjectException ioex = new InvalidObjectException("No field "+name+" of class "+clazz); throw ioex; } // field.setAccessible(true); ClassType fieldClassType = (ClassType) ValueWrapper.type(fieldRef); com.sun.jdi.Method setAccessibleMethod = ClassTypeWrapper.concreteMethodByName( fieldClassType, "setAccessible", "(Z)V"); try { ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setAccessibleMethod, Collections.singletonList(vm.mirrorOf(true)), ClassType.INVOKE_SINGLE_THREADED); // field.set(newInstance, fv); com.sun.jdi.Method setMethod = ClassTypeWrapper.concreteMethodByName( fieldClassType, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); if (fv instanceof PrimitiveValue) { PrimitiveType pt = (PrimitiveType) ValueWrapper.type(fv); ReferenceType fieldBoxingClass = EvaluatorVisitor.adjustBoxingType(clazz, pt, null); fv = EvaluatorVisitor.box((PrimitiveValue) fv, fieldBoxingClass, thread, null); } List<Value> args = Arrays.asList(new Value[] { obj, fv }); ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setMethod, args, ClassType.INVOKE_SINGLE_THREADED); } catch (InvocationException iex) { throw new InvalidObjectException( "Problem setting value "+fv+" to field "+name+" of class "+clazz+ " : "+iex.exception()); } }
private static ObjectReference getDeclaredOrInheritedField(ClassType clazz, String name, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException { //try { // java.lang.reflect.Field field = clazz.getDeclaredField(name); // return field; //} catch (NoSuchFieldException ex) {} ClassType classType = (ClassType) getOrLoadClass(vm, "java.lang.Class"); com.sun.jdi.Method getDeclaredFieldMethod = ClassTypeWrapper.concreteMethodByName( classType, "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); try { ObjectReference fieldRef = (ObjectReference) ObjectReferenceWrapper.invokeMethod(ReferenceTypeWrapper.classObject(clazz), thread, getDeclaredFieldMethod, Collections.singletonList(vm.mirrorOf(name)), ClassType.INVOKE_SINGLE_THREADED); return fieldRef; } catch (InvocationException ex) { // Likely NoSuchFieldException, try the super class... } //Class superClass = clazz.getSuperclass(); ClassType superClass = ClassTypeWrapper.superclass(clazz); if (superClass != null) { return getDeclaredOrInheritedField(superClass, name, vm, thread); } else { return null; } }
private InvocationExceptionTranslated(String invocationMessage, ObjectReference exeption, JPDADebuggerImpl debugger) { super(InvocationException.class.getName(), null); this.invocationMessage = invocationMessage; this.exeption = exeption; this.debugger = debugger; VirtualMachine evm = exeption.virtualMachine(); VirtualMachine dvm = debugger.getVirtualMachine(); if (evm != dvm) { logger.log(Level.INFO, invocationMessage+ ",\n evm = "+printVM(evm)+",\n dvm = "+printVM(dvm), // NOI18N new IllegalStateException("Stack Trace Info")); // NOI18N } this.createdAt = new Throwable().fillInStackTrace(); }
/** * Method invocation support. * Shared by ClassType and InterfaceType * @param threadIntf the thread in which to invoke. * @param methodIntf method the {@link Method} to invoke. * @param origArguments the list of {@link Value} arguments bound to the * invoked method. Values from the list are assigned to arguments * in the order they appear in the method signature. * @param options the integer bit flag options. * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this type, if the size of the argument list * does not match the number of declared arguments for the method, or * if the method is not static or is a static initializer. * @throws {@link InvalidTypeException} if any argument in the * argument list is not assignable to the corresponding method argument * type. * @throws ClassNotLoadedException if any argument type has not yet been loaded * through the appropriate class loader. * @throws IncompatibleThreadStateException if the specified thread has not * been suspended by an event. * @throws InvocationException if the method invocation resulted in * an exception in the target VM. * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be * loaded through the enclosing class's class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment * compatibility. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, List<? extends Value> origArguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { validateMirror(threadIntf); validateMirror(methodIntf); validateMirrorsOrNulls(origArguments); MethodImpl method = (MethodImpl) methodIntf; ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf; validateMethodInvocation(method); List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); ValueImpl[] args = arguments.toArray(new ValueImpl[0]); InvocationResult ret; try { PacketStream stream = sendInvokeCommand(thread, method, args, options); ret = waitForReply(stream); } catch (JDWPException exc) { if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { throw new IncompatibleThreadStateException(); } else { throw exc.toJDIException(); } } /* * There is an implict VM-wide suspend at the conclusion * of a normal (non-single-threaded) method invoke */ if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) { vm.notifySuspend(); } if (ret.getException() != null) { throw new InvocationException(ret.getException()); } else { return ret.getResult(); } }
private void validateMethodInvocation(Method method) throws InvalidTypeException, InvocationException { if (!canInvoke(method)) { throw new IllegalArgumentException("Invalid method"); } /* * Method must be a static and not a static initializer */ if (!method.isStatic()) { throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type"); } else if (method.isStaticInitializer()) { throw new IllegalArgumentException("Cannot invoke static initializer"); } }
@SuppressWarnings("unused") // called via reflection private void test3() throws Exception { System.out.println("DEBUG: ------------> Running test3"); try { for (int i = 0; i < 15; i++) { invoke("testPrimitiveArrRetval", "()[B", Collections.EMPTY_LIST, vm().mirrorOfVoid()); } } catch (InvocationException e) { handleFailure(e); } }
@SuppressWarnings("unused") // called via reflection private void test4() throws Exception { System.out.println("DEBUG: ------------> Running test4"); try { for (int i = 0; i < 15; i++) { invoke("testFooClsRetval", "()LOomDebugTestTarget$FooCls;", Collections.EMPTY_LIST, vm().mirrorOfVoid()); } } catch (InvocationException e) { handleFailure(e); } }
@SuppressWarnings({ "unused", "unchecked", "rawtypes" }) // called via reflection private void test5() throws Exception { System.out.println("DEBUG: ------------> Running test5"); try { ClassType type = (ClassType)thisObject.type(); for (int i = 0; i < 15; i++) { type.newInstance(mainThread, findMethod(targetClass, "<init>", "()V"), new ArrayList(0), ObjectReference.INVOKE_NONVIRTUAL); } } catch (InvocationException e) { handleFailure(e); } }
private void handleFailure(InvocationException e) { // There is no good way to see the OOME diagnostic message in the target since the // TestScaffold might throw an exception while trying to print the stack trace. I.e // it might get a a VMDisconnectedException before the stack trace printing finishes. System.err.println("FAILURE: InvocationException thrown. Trying to determine cause..."); defaultHandleOOMFailure(e); }
/** * Method invocation support. * Shared by ClassType and InterfaceType * @param threadIntf the thread in which to invoke. * @param methodIntf method the {@link Method} to invoke. * @param origArguments the list of {@link Value} arguments bound to the * invoked method. Values from the list are assigned to arguments * in the order they appear in the method signature. * @param options the integer bit flag options. * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this type, if the size of the argument list * does not match the number of declared arguments for the method, or * if the method is not static or is a static initializer. * @throws InvalidTypeException if any argument in the * argument list is not assignable to the corresponding method argument * type. * @throws ClassNotLoadedException if any argument type has not yet been loaded * through the appropriate class loader. * @throws IncompatibleThreadStateException if the specified thread has not * been suspended by an event. * @throws InvocationException if the method invocation resulted in * an exception in the target VM. * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be * loaded through the enclosing class's class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment * compatibility. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, List<? extends Value> origArguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { validateMirror(threadIntf); validateMirror(methodIntf); validateMirrorsOrNulls(origArguments); MethodImpl method = (MethodImpl) methodIntf; ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf; validateMethodInvocation(method); List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); ValueImpl[] args = arguments.toArray(new ValueImpl[0]); InvocationResult ret; try { PacketStream stream = sendInvokeCommand(thread, method, args, options); ret = waitForReply(stream); } catch (JDWPException exc) { if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { throw new IncompatibleThreadStateException(); } else { throw exc.toJDIException(); } } /* * There is an implict VM-wide suspend at the conclusion * of a normal (non-single-threaded) method invoke */ if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) { vm.notifySuspend(); } if (ret.getException() != null) { throw new InvocationException(ret.getException()); } else { return ret.getResult(); } }
void validateIfaceMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * For nonvirtual invokes, method must have a body */ if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } } }
public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, List arguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { vm.throwNotReadOnlyException("ClassType.invokeMethod(...)"); return null; }
public ObjectReference newInstance(ThreadReference threadIntf, Method methodIntf, List arguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { vm.throwNotReadOnlyException("ClassType.newInstance(...)"); return null; }