/** * 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)); } } }
@Override public void setValue(Value value) { try { if (fieldObject != null) { fieldObject.setValue(field, value); } else { ((ClassType) field.declaringType()).setValue(field, value); } } catch (IllegalArgumentException iaex) { throw new IllegalStateException(new InvalidExpressionException (iaex)); } catch (InvalidTypeException itex) { throw new IllegalStateException(new InvalidExpressionException (itex)); } catch (ClassNotLoadedException cnlex) { throw new IllegalStateException(cnlex); } }
Type findType(String signature) throws ClassNotLoadedException { Type type; if (signature.length() == 1) { /* OTI FIX: Must be a primitive type or the void type */ char sig = signature.charAt(0); if (sig == 'V') { type = vm.theVoidType(); } else { type = vm.primitiveTypeMirror((byte)sig); } } else { // Must be a reference type. ClassLoaderReferenceImpl loader = (ClassLoaderReferenceImpl)classLoader(); if ((loader == null) || (isPrimitiveArray(signature)) //Work around 4450091 ) { // Caller wants type of boot class field type = vm.findBootType(signature); } else { // Caller wants type of non-boot class field type = loader.findType(signature); } } return type; }
ValueImpl convertForAssignmentTo(ValueContainer destination) throws InvalidTypeException { /* * TO DO: Centralize JNI signature knowledge */ if (destination.signature().length() > 1) { throw new InvalidTypeException("Can't assign primitive value to object"); } if ((destination.signature().charAt(0) == 'Z') && (type().signature().charAt(0) != 'Z')) { throw new InvalidTypeException("Can't assign non-boolean value to a boolean"); } if ((destination.signature().charAt(0) != 'Z') && (type().signature().charAt(0) == 'Z')) { throw new InvalidTypeException("Can't assign boolean value to an non-boolean"); } if ("void".equals(destination.typeName())) { throw new InvalidTypeException("Can't assign primitive value to a void"); } try { PrimitiveTypeImpl primitiveType = (PrimitiveTypeImpl)destination.type(); return (ValueImpl)(primitiveType.convert(this)); } catch (ClassNotLoadedException e) { throw new InternalException("Signature and type inconsistent for: " + destination.typeName()); } }
static ValueImpl prepareForAssignment(Value value, ValueContainer destination) throws InvalidTypeException, ClassNotLoadedException { if (value == null) { /* * TO DO: Centralize JNI signature knowledge */ if (destination.signature().length() == 1) { throw new InvalidTypeException("Can't set a primitive type to null"); } return null; // no further checking or conversion necessary } else { return ((ValueImpl)value).prepareForAssignmentTo(destination); } }
Type findComponentType(String signature) throws ClassNotLoadedException { byte tag = (byte)signature.charAt(0); if (PacketStream.isObjectTag(tag)) { // It's a reference type JNITypeParser parser = new JNITypeParser(componentSignature()); List<ReferenceType> list = vm.classesByName(parser.typeName()); Iterator<ReferenceType> iter = list.iterator(); while (iter.hasNext()) { ReferenceType type = iter.next(); ClassLoaderReference cl = type.classLoader(); if ((cl == null)? (classLoader() == null) : (cl.equals(classLoader()))) { return type; } } // Component class has not yet been loaded throw new ClassNotLoadedException(componentTypeName()); } else { // It's a primitive type return vm.primitiveTypeMirror(tag); } }
boolean isAssignableTo(ReferenceType destType) { if (destType instanceof ArrayType) { try { Type destComponentType = ((ArrayType)destType).componentType(); return isComponentAssignable(destComponentType, componentType()); } catch (ClassNotLoadedException e) { // One or both component types has not yet been // loaded => can't assign return false; } } else if (destType instanceof InterfaceType) { // Only valid InterfaceType assignee is Cloneable return destType.name().equals("java.lang.Cloneable"); } else { // Only valid ClassType assignee is Object return destType.name().equals("java.lang.Object"); } }
private Value handleSetValueForObject(String name, String belongToClass, String valueString, ObjectReference container, Map<String, Object> options) throws InvalidTypeException, ClassNotLoadedException { Value newValue; if (container instanceof ArrayReference) { ArrayReference array = (ArrayReference) container; Type eleType = ((ArrayType) array.referenceType()).componentType(); newValue = setArrayValue(array, eleType, Integer.parseInt(name), valueString, options); } else { if (StringUtils.isBlank(belongToClass)) { Field field = container.referenceType().fieldByName(name); if (field != null) { if (field.isStatic()) { newValue = this.setStaticFieldValue(container.referenceType(), field, name, valueString, options); } else { newValue = this.setObjectFieldValue(container, field, name, valueString, options); } } else { throw new IllegalArgumentException( String.format("SetVariableRequest: Variable %s cannot be found.", name)); } } else { newValue = setFieldValueWithConflict(container, container.referenceType().allFields(), name, belongToClass, valueString, options); } } return newValue; }
private Value setFieldValueWithConflict(ObjectReference obj, List<Field> fields, String name, String belongToClass, String value, Map<String, Object> options) throws ClassNotLoadedException, InvalidTypeException { Field field; // first try to resolve field by fully qualified name List<Field> narrowedFields = fields.stream().filter(TypeComponent::isStatic) .filter(t -> t.name().equals(name) && t.declaringType().name().equals(belongToClass)) .collect(Collectors.toList()); if (narrowedFields.isEmpty()) { // second try to resolve field by formatted name narrowedFields = fields.stream().filter(TypeComponent::isStatic) .filter(t -> t.name().equals(name) && context.getVariableFormatter().typeToString(t.declaringType(), options).equals(belongToClass)) .collect(Collectors.toList()); } if (narrowedFields.size() == 1) { field = narrowedFields.get(0); } else { throw new UnsupportedOperationException(String.format("SetVariableRequest: Name conflicted for %s.", name)); } return field.isStatic() ? setStaticFieldValue(field.declaringType(), field, name, value, options) : this.setObjectFieldValue(obj, field, name, value, options); }
Type findType(String signature) throws ClassNotLoadedException { Type type; if (signature.length() == 1) { /* OTI FIX: Must be a primitive type or the void type */ char sig = signature.charAt(0); if (sig == 'V') { type = vm.theVoidType(); } else { type = vm.primitiveTypeMirror(sig); } } else { // Must be a reference type. ClassLoaderReferenceImpl loader = (ClassLoaderReferenceImpl)classLoader(); if ((loader == null) || (isPrimitiveArray(signature)) //Work around 4450091 ) { // Caller wants type of boot class field type = vm.findBootType(signature); } else { // Caller wants type of non-boot class field type = loader.findType(signature); } } return type; }
boolean isAssignableTo(ReferenceType destType) { if (destType instanceof ArrayType) { try { Type destComponentType = ((ArrayType)destType).componentType(); return isComponentAssignable(destComponentType, componentType()); } catch (ClassNotLoadedException e) { // One or both component types has not yet been // loaded => can't assign return false; } } else { Symbol typeName = ((ReferenceTypeImpl)destType).typeNameAsSymbol(); if (destType instanceof InterfaceType) { // Every array type implements java.io.Serializable and // java.lang.Cloneable. fixme in JVMDI-JDI, includes only // Cloneable but not Serializable. return typeName.equals(vm.javaLangCloneable()) || typeName.equals(vm.javaIoSerializable()); } else { // Only valid ClassType assignee is Object return typeName.equals(vm.javaLangObject()); } } }
int getModifiers() { /* * For object arrays, the return values for Interface * Accessible.isPrivate(), Accessible.isProtected(), * etc... are the same as would be returned for the * component type. Fetch the modifier bits from the * component type and use those. * * For primitive arrays, the modifiers are always * VMModifiers.FINAL | VMModifiers.PUBLIC * * Reference com.sun.jdi.Accessible.java. */ try { Type t = componentType(); if (t instanceof PrimitiveType) { return VMModifiers.FINAL | VMModifiers.PUBLIC; } else { ReferenceType rt = (ReferenceType)t; return rt.modifiers(); } } catch (ClassNotLoadedException cnle) { cnle.printStackTrace(); } return -1; }
private void createVariable(final LocalVariable var, final int lineFrom, final int lineTo, final IMethodNode methodNode) { ITypeNodeRef varTypeNode; try { varTypeNode = upstream.resolveType(var.type().signature(), var.typeName()); } catch (final ClassNotLoadedException e) { varTypeNode = modelFactory().lookupTypeRefByName(var.typeName()); } methodNode.addDataMember(var.name(), lineFrom, lineTo, varTypeNode, NO_JDI, createModifiers(var), NodeVisibility.NV_LOCAL, model.valueFactory() .createUninitializedValue()); }
void createField(final Field field, final int lineFrom, final int lineTo, final ITypeNode typeNode) { // this field never generates a field read or field write event if (!filter.acceptsType(field.declaringType()) || !filter.acceptsField(field)) { return; } ITypeNodeRef fieldTypeNode; try { fieldTypeNode = upstream.resolveType(field.type().signature(), field.typeName()); } catch (final ClassNotLoadedException e) { fieldTypeNode = modelFactory().lookupTypeRefByName(field.typeName()); } typeNode.addDataMember(field.name(), lineFrom, lineTo, fieldTypeNode, NO_JDI, createModifiers(field), createVisibility(field), fieldTypeNode instanceof ITypeNode ? ((ITypeNode) fieldTypeNode).defaultValue() : model .valueFactory().createNullValue()); }
public void jdiTypeLoadArray(final ArrayType type) { try { final Type componentType = type.componentType(); if (componentType instanceof ReferenceType) { jdiTypeLoad(((ReferenceType) componentType)); } } catch (final ClassNotLoadedException e) { System.err.println("Error: type not loaded for array '" + type.signature() + "'"); // String componentTypeName = type.signature(); componentTypeName = componentTypeName.substring(componentTypeName.lastIndexOf('[') + 1); // registry.getTypeId(componentTypeName); } jdiTypeLoadComplete(type); }
/** * * @param type the type of the field on which this watchpoint is registered */ public void setField(Field field) { try { this.field = field; this.type = field.type(); } catch (ClassNotLoadedException e) { e.printStackTrace(); } }
public void doEffect(RVal preVal, RVal postVal) throws InvalidTypeException, ClassNotLoadedException { if (postVal instanceof ArrayValue) { ArrayValue postArrVal = ((ArrayValue)postVal); if (preVal.getValue() instanceof ArrayReference) { ArrayReference preArrVal = (ArrayReference)preVal.getValue(); if (postArrVal.getValue() instanceof ArrayReference && ((ArrayReference)postArrVal.getValue()).uniqueID() == preArrVal.uniqueID()) { // If it's the same array just with different values, we can reset the values directly. postArrVal.resetTo(preArrVal); return; } } // We must reset the original array's values and reset to it. postArrVal.resetTo((ArrayReference)postArrVal.getValue()); } lval.setValue(postVal.getValue()); }
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 ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes, ByteValue[] mirrorBytesCache) throws InvalidTypeException, ClassNotLoadedException, InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper, UnsupportedOperationExceptionWrapper { ArrayType bytesArrayClass = getArrayClass(vm, "byte[]"); ArrayReference array = null; boolean disabledCollection = false; while (!disabledCollection) { array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length); try { ObjectReferenceWrapper.disableCollection(array); disabledCollection = true; } catch (ObjectCollectedExceptionWrapper ocex) { // Collected too soon, try again... } } List<Value> values = new ArrayList<Value>(bytes.length); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; ByteValue mb = mirrorBytesCache[128 + b]; if (mb == null) { mb = VirtualMachineWrapper.mirrorOf(vm, b); mirrorBytesCache[128 + b] = mb; } values.add(mb); } ArrayReferenceWrapper.setValues(array, values); return array; }
public boolean sendStopUserCode() throws IllegalStateException { if (closed) { return false; } vm.suspend(); try { ObjectReference myRef = getAgentObjectReference(); OUTER: for (ThreadReference thread : vm.allThreads()) { // could also tag the thread (e.g. using name), to find it easier AGENT: for (StackFrame frame : thread.frames()) { if (REMOTE_AGENT_CLASS.equals(frame.location().declaringType().name())) { String n = frame.location().method().name(); if (AGENT_INVOKE_METHOD.equals(n) || AGENT_VARVALUE_METHOD.equals(n)) { ObjectReference thiz = frame.thisObject(); if (myRef != null && myRef != thiz) { break AGENT; } if (((BooleanValue) thiz.getValue(thiz.referenceType().fieldByName("inClientCode"))).value()) { thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(true)); ObjectReference stopInstance = (ObjectReference) thiz.getValue(thiz.referenceType().fieldByName("stopException")); vm.resume(); thread.stop(stopInstance); thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(false)); } return true; } } } } } catch (ClassNotLoadedException | IncompatibleThreadStateException | InvalidTypeException ex) { throw new IllegalStateException(ex); } finally { vm.resume(); } return false; }
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 static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes, ByteValue[] mirrorBytesCache) throws InvalidTypeException, ClassNotLoadedException, InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper { ArrayType bytesArrayClass = getArrayClass(vm, "byte[]"); ArrayReference array = null; boolean disabledCollection = false; while (!disabledCollection) { array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length); try { ObjectReferenceWrapper.disableCollection(array); disabledCollection = true; } catch (ObjectCollectedExceptionWrapper ocex) { // Collected too soon, try again... } catch (UnsupportedOperationExceptionWrapper uex) { // Hope it will not be GC'ed... disabledCollection = true; } } List<Value> values = new ArrayList<Value>(bytes.length); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; ByteValue mb = mirrorBytesCache[128 + b]; if (mb == null) { mb = VirtualMachineWrapper.mirrorOf(vm, b); mirrorBytesCache[128 + b] = mb; } values.add(mb); } ArrayReferenceWrapper.setValues(array, values); return array; }
private static Method getConcreteMethod2(ReferenceType type, String methodName, List<? extends Type> typeArguments) throws UnsuitableArgumentsException { List<Method> methods = type.methodsByName(methodName); List<Method> possibleMethods = new ArrayList<Method>(); List<Method> methodsWithArgTypesNotLoaded = null; boolean constructor = "<init>".equals(methodName); for (Method method : methods) { if (!method.isAbstract() && (!constructor || type.equals(method.declaringType()))) { try { if (equalTypes(method.argumentTypes(), typeArguments)) { return method; } if (acceptTypes(method.argumentTypes(), typeArguments)) { possibleMethods.add(method); } } catch (ClassNotLoadedException ex) { if (method.argumentTypeNames().size() == typeArguments.size()) { if (methodsWithArgTypesNotLoaded == null) { methodsWithArgTypesNotLoaded = new ArrayList<Method>(); } methodsWithArgTypesNotLoaded.add(method); } } } } if (possibleMethods.isEmpty()) { if (methods.size() > 0) { if (methodsWithArgTypesNotLoaded != null) { // Workaround for cases when we're not able to test method types. return methodsWithArgTypesNotLoaded.get(0); } throw new UnsuitableArgumentsException(); } return null; } return possibleMethods.get(0); }
@Override public void setValue(Value value) { try { context.getFrame().setValue(var, value); } catch (InvalidTypeException itex) { throw new IllegalStateException(new InvalidExpressionException (itex)); } catch (ClassNotLoadedException cnlex) { throw new IllegalStateException(cnlex); } }
/** * 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(); } }
Type findType(String signature) throws ClassNotLoadedException { List<ReferenceType> types = visibleClasses(); Iterator<ReferenceType> iter = types.iterator(); while (iter.hasNext()) { ReferenceType type = iter.next(); if (type.signature().equals(signature)) { return type; } } JNITypeParser parser = new JNITypeParser(signature); throw new ClassNotLoadedException(parser.typeName(), "Class " + parser.typeName() + " not loaded"); }
public List<Type> argumentTypes() throws ClassNotLoadedException { int size = argumentSignatures().size(); List<Type> types = new ArrayList<>(size); for (int i = 0; i < size; i++) { Type type = argumentType(i); types.add(type); } return types; }
List<Value> validateAndPrepareArgumentsForInvoke(List<? extends Value> origArguments) throws ClassNotLoadedException, InvalidTypeException { List<Value> arguments = new ArrayList<>(origArguments); if (isVarArgs()) { handleVarArgs(arguments); } int argSize = arguments.size(); JNITypeParser parser = new JNITypeParser(signature()); List<String> signatures = parser.argumentSignatures(); if (signatures.size() != argSize) { throw new IllegalArgumentException("Invalid argument count: expected " + signatures.size() + ", received " + arguments.size()); } for (int i = 0; i < argSize; i++) { Value value = arguments.get(i); value = ValueImpl.prepareForAssignment(value, new ArgumentContainer(i)); arguments.set(i, value); } return arguments; }
/** * 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(); } }
ValueImpl prepareForAssignmentTo(ValueContainer destination) throws InvalidTypeException, ClassNotLoadedException { validateAssignment(destination); return this; // conversion never necessary }
void validateAssignment(ValueContainer destination) throws InvalidTypeException, ClassNotLoadedException { /* * Do these simpler checks before attempting a query of the destination's * type which might cause a confusing ClassNotLoadedException if * the destination is primitive or an array. */ /* * TO DO: Centralize JNI signature knowledge */ if (destination.signature().length() == 1) { throw new InvalidTypeException("Can't assign object value to primitive"); } if ((destination.signature().charAt(0) == '[') && (type().signature().charAt(0) != '[')) { throw new InvalidTypeException("Can't assign non-array value to an array"); } if ("void".equals(destination.typeName())) { throw new InvalidTypeException("Can't assign object value to a void"); } // Validate assignment ReferenceType destType = (ReferenceTypeImpl)destination.type(); ReferenceTypeImpl myType = (ReferenceTypeImpl)referenceType(); if (!myType.isAssignableTo(destType)) { JNITypeParser parser = new JNITypeParser(destType.signature()); String destTypeName = parser.typeName(); throw new InvalidTypeException("Can't assign " + type().name() + " to " + destTypeName); } }
public void setValue(Field field, Value value) throws InvalidTypeException, ClassNotLoadedException { validateMirror(field); validateMirrorOrNull(value); validateFieldSet(field); // More validation specific to setting from a ClassType if(!field.isStatic()) { throw new IllegalArgumentException( "Must set non-static field through an instance"); } try { JDWP.ClassType.SetValues.FieldValue[] values = new JDWP.ClassType.SetValues.FieldValue[1]; values[0] = new JDWP.ClassType.SetValues.FieldValue( ((FieldImpl)field).ref(), // validate and convert if necessary ValueImpl.prepareForAssignment(value, (FieldImpl)field)); try { JDWP.ClassType.SetValues.process(vm, this, values); } catch (JDWPException exc) { throw exc.toJDIException(); } } catch (ClassNotLoadedException e) { /* * Since we got this exception, * the field type must be a reference type. The value * we're trying to set is null, but if the field's * class has not yet been loaded through the enclosing * class loader, then setting to null is essentially a * no-op, and we should allow it without an exception. */ if (value != null) { throw e; } } }
public void setValue(int index, Value value) throws InvalidTypeException, ClassNotLoadedException { List<Value> list = new ArrayList<Value>(1); list.add(value); setValues(index, list, 0, 1); }
Type findBootType(String signature) throws ClassNotLoadedException { List<ReferenceType> types = retrieveClassesBySignature(signature); Iterator<ReferenceType> iter = types.iterator(); while (iter.hasNext()) { ReferenceType type = iter.next(); if (type.classLoader() == null) { return type; } } JNITypeParser parser = new JNITypeParser(signature); throw new ClassNotLoadedException(parser.typeName(), "Type " + parser.typeName() + " not loaded"); }
void getModifiers() { if (modifiers != -1) { return; } /* * For object arrays, the return values for Interface * Accessible.isPrivate(), Accessible.isProtected(), * etc... are the same as would be returned for the * component type. Fetch the modifier bits from the * component type and use those. * * For primitive arrays, the modifiers are always * VMModifiers.FINAL | VMModifiers.PUBLIC * * Reference com.sun.jdi.Accessible.java. */ try { Type t = componentType(); if (t instanceof PrimitiveType) { modifiers = VMModifiers.FINAL | VMModifiers.PUBLIC; } else { ReferenceType rt = (ReferenceType)t; modifiers = rt.modifiers(); } } catch (ClassNotLoadedException cnle) { cnle.printStackTrace(); } }
private Value handleSetValueForStackFrame(String name, String belongToClass, String valueString, boolean showStaticVariables, StackFrame container, Map<String, Object> options) throws AbsentInformationException, InvalidTypeException, ClassNotLoadedException { Value newValue; if (name.equals("this")) { throw new UnsupportedOperationException("SetVariableRequest: 'This' variable cannot be changed."); } LocalVariable variable = container.visibleVariableByName(name); if (StringUtils.isBlank(belongToClass) && variable != null) { newValue = this.setFrameValue(container, variable, valueString, options); } else { if (showStaticVariables && container.location().method().isStatic()) { ReferenceType type = container.location().declaringType(); if (StringUtils.isBlank(belongToClass)) { Field field = type.fieldByName(name); newValue = setStaticFieldValue(type, field, name, valueString, options); } else { newValue = setFieldValueWithConflict(null, type.allFields(), name, belongToClass, valueString, options); } } else { throw new UnsupportedOperationException( String.format("SetVariableRequest: Variable %s cannot be found.", name)); } } return newValue; }