@SuppressWarnings("unused") // called via reflection private void test2() throws Exception { System.out.println("DEBUG: ------------> Running test2"); try { Field field = targetClass.fieldByName("byteArray"); ArrayType arrType = (ArrayType)field.type(); for (int i = 0; i < 15; i++) { ArrayReference byteArrayVal = arrType.newInstance(3000000); if (byteArrayVal.isCollected()) { System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP."); continue; } invoke("testPrimitive", "([B)V", byteArrayVal); } } catch (VMOutOfMemoryException e) { defaultHandleOOMFailure(e); } }
static ArrayType getArrayClass(VirtualMachine vm, String name) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper { List<ReferenceType> classList = VirtualMachineWrapper.classesByName(vm, name); ReferenceType clazz = null; for (ReferenceType c : classList) { if (ReferenceTypeWrapper.classLoader(c) == null) { clazz = c; break; } } return (ArrayType) clazz; }
/** * Creates a new translated node for given original one. * * @param o a node to be translated * @return a new translated node */ private Object createTranslation (Object o) { switch (translationID) { case THREAD_ID: if (o instanceof ThreadReference) { return new JPDAThreadImpl ((ThreadReference) o, debugger); } else if (o instanceof ThreadGroupReference) { return new JPDAThreadGroupImpl ((ThreadGroupReference) o, debugger); } else { return null; } case LOCALS_ID: if (o instanceof ArrayType) { return new JPDAArrayTypeImpl(debugger, (ArrayType) o); } if (o instanceof ReferenceType) { return new JPDAClassTypeImpl(debugger, (ReferenceType) o); } default: throw new IllegalStateException(""+o); } }
private ArrayType getArrayType(NewArrayTree arg0, Type type, int depth, EvaluationContext evaluationContext) { String arrayClassName; if (depth < BRACKETS.length()/2) { arrayClassName = type.name() + BRACKETS.substring(0, 2*depth); } else { arrayClassName = type.name() + BRACKETS; for (int i = BRACKETS.length()/2; i < depth; i++) { arrayClassName += "[]"; // NOI18N } } ReferenceType rt = getOrLoadClass(type.virtualMachine(), arrayClassName, evaluationContext); if (rt == null) { Assert.error(arg0, "unknownType", arrayClassName); } return (ArrayType) rt; }
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; }
/** * Test whether the value has referenced objects. * * @param value * the value. * @param includeStatic * whether or not the static fields are visible. * @return true if this value is reference objects. */ public static boolean hasChildren(Value value, boolean includeStatic) { if (value == null) { return false; } Type type = value.type(); if (type instanceof ArrayType) { return ((ArrayReference) value).length() > 0; } return value.type() instanceof ReferenceType && ((ReferenceType) type).allFields().stream() .filter(t -> includeStatic || !t.isStatic()).toArray().length > 0; }
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()); } } }
private boolean visitArrayCells(final Location location, final StackFrame frame, final ArrayReference arrayRef) { // only process small arrays if (!manager().generateArrayEvents() || arrayRef == null || arrayRef.length() > EventFactoryAdapter.SMALL_ARRAY_SIZE) { return false; } // retrieve the array reference type final ArrayType at = (ArrayType) arrayRef.type(); // retrieve the array contour final IContextContour array = contourFactory().lookupInstanceContour(at.name(), arrayRef.uniqueID()); // make sure the respective array contour exists if (array == null) { return false; } return visitArrayCells(location, frame, arrayRef, array); }
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); }
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 JPDAArrayTypeImpl(JPDADebuggerImpl debugger, ArrayType arrayType) { super(debugger, arrayType); this.arrayType = arrayType; }
private static ArrayType getArrayClass(VirtualMachine vm, String name) throws InternalExceptionWrapper, ObjectCollectedExceptionWrapper, VMDisconnectedExceptionWrapper { List<ReferenceType> classList = VirtualMachineWrapper.classesByName(vm, name); ReferenceType clazz = null; for (ReferenceType c : classList) { if (ReferenceTypeWrapper.classLoader(c) == null) { clazz = c; break; } } return (ArrayType) clazz; }
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 String getTypeName(TypeMirror type) { if (type.getKind() == TypeKind.ARRAY) { return getTypeName(((javax.lang.model.type.ArrayType) type).getComponentType())+"[]"; } if (type.getKind() == TypeKind.TYPEVAR) { TypeVariable tv = (TypeVariable) type; return getTypeName(tv.getUpperBound()); } if (type.getKind() == TypeKind.DECLARED) { return ElementUtilities.getBinaryName((TypeElement) ((DeclaredType) type).asElement()); } return type.toString(); }
private static ArrayReference createArrayMirrorWithDisabledCollection(ArrayType arrayType, int dimension, EvaluationContext evaluationContext) { ArrayReference array; do { array = arrayType.newInstance(dimension); try { evaluationContext.disableCollectionOf(array); } catch (ObjectCollectedException oce) { array = null; // Already collected! Create a new value and try again... } } while (array == null); return array; }
public ArrayReference newInstance(int length) { try { return (ArrayReference)JDWP.ArrayType.NewInstance. process(vm, this, length).newArray; } catch (JDWPException exc) { throw exc.toJDIException(); } }
/** * Get the variables of the object. * * @param obj * the object * @return the variable list * @throws AbsentInformationException * when there is any error in retrieving information */ public static List<Variable> listFieldVariables(ObjectReference obj, boolean includeStatic) throws AbsentInformationException { List<Variable> res = new ArrayList<>(); Type type = obj.type(); if (type instanceof ArrayType) { int arrayIndex = 0; for (Value elementValue : ((ArrayReference) obj).getValues()) { Variable ele = new Variable(String.valueOf(arrayIndex++), elementValue); res.add(ele); } return res; } List<Field> fields = obj.referenceType().allFields().stream().filter(t -> includeStatic || !t.isStatic()) .sorted((a, b) -> { try { boolean v1isStatic = a.isStatic(); boolean v2isStatic = b.isStatic(); if (v1isStatic && !v2isStatic) { return -1; } if (!v1isStatic && v2isStatic) { return 1; } return a.name().compareToIgnoreCase(b.name()); } catch (Exception e) { logger.log(Level.SEVERE, String.format("Cannot sort fields: %s", e), e); return -1; } }).collect(Collectors.toList()); fields.forEach(f -> { Variable var = new Variable(f.name(), obj.getValue(f)); var.field = f; res.add(var); }); return res; }
/** * Get the variables of the object with pagination. * * @param obj * the object * @param start * the start of the pagination * @param count * the number of variables needed * @return the variable list * @throws AbsentInformationException * when there is any error in retrieving information */ public static List<Variable> listFieldVariables(ObjectReference obj, int start, int count) throws AbsentInformationException { List<Variable> res = new ArrayList<>(); Type type = obj.type(); if (type instanceof ArrayType) { int arrayIndex = start; for (Value elementValue : ((ArrayReference) obj).getValues(start, count)) { res.add(new Variable(String.valueOf(arrayIndex++), elementValue)); } return res; } throw new UnsupportedOperationException("Only Array type is supported."); }
private String getGenericName(ReferenceType type) throws DebugException { if (type instanceof ArrayType) { try { Type componentType; componentType = ((ArrayType) type).componentType(); if (componentType instanceof ReferenceType) { return getGenericName((ReferenceType) componentType) + "[]"; //$NON-NLS-1$ } return type.name(); } catch (ClassNotLoadedException e) { // we cannot create the generic name using the component type, // just try to create one with the information } } String signature = type.signature(); StringBuffer res = new StringBuffer(getTypeName(signature)); String genericSignature = type.genericSignature(); if (genericSignature != null) { String[] typeParameters = Signature.getTypeParameters(genericSignature); if (typeParameters.length > 0) { res.append('<').append(Signature.getTypeVariable(typeParameters[0])); for (int i = 1; i < typeParameters.length; i++) { res.append(',').append(Signature.getTypeVariable(typeParameters[i])); } res.append('>'); } } return res.toString(); }
public boolean isApplicable(Type type) { return (type instanceof ArrayType); }
public static F3ReferenceType wrap(F3VirtualMachine f3vm, ReferenceType rt) { if (rt == null) { return null; } else if (rt instanceof ClassType) { return f3vm.classType((ClassType)rt); } else if (rt instanceof InterfaceType) { return f3vm.interfaceType((InterfaceType)rt); } else if (rt instanceof ArrayType) { return f3vm.arrayType((ArrayType)rt); } else { return f3vm.referenceType(rt); } }
@Override protected ArrayType underlying() { return (ArrayType) super.underlying(); }
protected F3ArrayType arrayType(ArrayType at) { synchronized (at) { if (! refTypesCache.containsKey(at)) { refTypesCache.put(at, new F3ArrayType(this, at)); } return (F3ArrayType) refTypesCache.get(at); } }
private boolean visitArrayCells(final Location location, final StackFrame frame, final ArrayReference arrayRef, final IContextContour array) { boolean modified = false; // retrieve the array values final List<Value> values = arrayRef.length() > 0 ? arrayRef.getValues() : null; // check for modifications on each of the array cells for (int i = 0; values != null && i < values.size(); i++) { final IContourMember cell = array.lookupMember(i); final Value cellValue = values.get(i); // recursively process the array reference value if (cellValue instanceof ArrayReference) { if (!handleNewArray((ArrayReference) cellValue, location, frame) && EventFactoryAdapter.PROCESS_MULTI_ARRAY) { final ArrayReference innerArray = (ArrayReference) cellValue; // retrieve the array reference type final ArrayType at = (ArrayType) cellValue.type(); // retrieve the array contour final IContextContour innerContour = contourFactory().lookupInstanceContour(at.name(), innerArray.uniqueID()); visitArrayCells(location, frame, innerArray, innerContour); } } // true if the variable was newly observed or its value changed if (executionState().observedVariable(cell, cellValue, frame.thread(), location.lineNumber())) { // dispatch the assignment to the modified cell dispatcher().dispatchArrayCellWriteEvent(location, frame.thread(), array, cell, cellValue, ((ArrayType) arrayRef.type()).componentTypeName()); modified = true; } } return modified; }
/** * Class processing creates all the necessary static and instance schemas, and dispatches any * necessary class load events, from the most general to the most specific class. */ void handleTypeLoad(final ReferenceType type, final ThreadReference thread) { if (type instanceof ClassType) { handleClassLoad((ClassType) type, thread); } else if (type instanceof InterfaceType) { handleInterfaceLoad((InterfaceType) type, thread); } // resolve the array's type else if (manager().generateArrayEvents() && type instanceof ArrayType) { final ArrayType at = (ArrayType) type; try { if (at.componentType() instanceof ReferenceType) { handleTypeLoad(((ReferenceType) at.componentType()), thread); } resolveType(type); } catch (final ClassNotLoadedException e) { System.err.println("TYPE_NOT_LOADED_FOR_ARRAY[" + type.signature() + "]"); // e.printStackTrace(); String componentTypeName = type.signature(); componentTypeName = componentTypeName.substring(componentTypeName.lastIndexOf('[') + 1); final ITypeNodeRef result = staticModelFactory().lookupTypeNode(componentTypeName); if (result != null) { System.err.println("TYPE_LOADED_FOR_ARRAY[" + type.signature() + "]"); resolveType(type); } else { System.err.println("IGNORING_COMPONENT_TYPE_FOR_ARRAY[" + type.signature() + "]"); resolveType(type); } } } }
public void jdiTypeLoad(final ReferenceType type) { if (registry.contains(type)) { return; } if (type instanceof ClassType) { jdiTypeLoadClass((ClassType) type); } else if (type instanceof InterfaceType) { jdiTypeLoadInterface((InterfaceType) type); } else if (type instanceof ArrayType) { jdiTypeLoadArray((ArrayType) type); } }
/** @return true if t1 extends t2 */ private static boolean extendsType(ReferenceType t1, ReferenceType t2) { if (t2 instanceof InterfaceType) { List<InterfaceType> superInterfaces; if (t1 instanceof ClassType) { superInterfaces = ((ClassType) t1).allInterfaces(); } else if (t1 instanceof InterfaceType) { superInterfaces = ((InterfaceType) t1).superinterfaces(); } else { return false; } return superInterfaces.contains((InterfaceType) t2); } if (t2 instanceof ClassType) { if (t1 instanceof ClassType) { ClassType superClass = ((ClassType) t1).superclass(); if (superClass != null) { if (superClass.equals((ClassType) t2)) { return true; } else { return extendsType(superClass, t2); } } else { return false; } } else { return false; } } if (t2 instanceof ArrayType) { if (t1 instanceof ArrayType) { try { Type ct1 = ((ArrayType) t1).componentType(); Type ct2 = ((ArrayType) t2).componentType(); return extendsType(ct1, ct2); } catch (ClassNotLoadedException cnlex) { return false; } } else { return false; } } else { throw new IllegalStateException("Unknown ReferenceType: "+t2); } }
@Test public void testHasChildren() throws Exception { ObjectReference foo = this.getObjectReference("Foo"); assertTrue("class Foo should have children", VariableUtils.hasChildren(foo, true)); assertTrue("class Foo should have children", VariableUtils.hasChildren(foo, false)); Value string = this.getLocalValue("str"); assertTrue("String object should have children", VariableUtils.hasChildren(string, true)); assertTrue("String object should have children", VariableUtils.hasChildren(string, false)); ArrayReference arrays = (ArrayReference) this.getLocalValue("arrays"); assertTrue("Array object with elements should have children", VariableUtils.hasChildren( arrays, true)); assertTrue("Array object with elements should have children", VariableUtils.hasChildren( arrays, false)); assertFalse("Array object with no elements should not have children", VariableUtils.hasChildren( ((ArrayType) arrays.type()).newInstance(0), true)); assertFalse("Array object with no elements should not have children", VariableUtils.hasChildren( ((ArrayType) arrays.type()).newInstance(0), false)); assertTrue("List object with elements should have children", VariableUtils.hasChildren( this.getLocalValue("strList"), false)); assertFalse("Object should not have children", VariableUtils.hasChildren(this.getLocalValue("obj"), true)); assertFalse("Object should not have children", VariableUtils.hasChildren(this.getLocalValue("obj"), false)); assertTrue("Class object should have children", VariableUtils.hasChildren(this.getLocalValue("b"), false)); assertTrue("Class object should have children", VariableUtils.hasChildren(this.getLocalValue("b"), false)); assertFalse("Null object should not have children", VariableUtils.hasChildren(null, true)); assertFalse("Null object should not have children", VariableUtils.hasChildren(null, false)); assertTrue("Boolean object should have children", VariableUtils.hasChildren(getLocalValue("boolVar"), false)); assertFalse("boolean object should not have children", VariableUtils.hasChildren(getVM().mirrorOf(true), false)); assertFalse("Class with no fields should not have children", VariableUtils.hasChildren(this.getLocalValue("a"), true)); assertFalse("Class with no fields should not have children", VariableUtils.hasChildren(this.getLocalValue("a"), false)); assertFalse("Primitive object should not have children", VariableUtils.hasChildren( getVM().mirrorOf(1), true)); assertFalse("Primitive object should not have children", VariableUtils.hasChildren( getVM().mirrorOf(true), true)); assertFalse("Primitive object should not have children", VariableUtils.hasChildren( getVM().mirrorOf('c'), true)); assertFalse("Primitive object should not have children", VariableUtils.hasChildren( getVM().mirrorOf(1000L), true)); }
public static F3ArrayType wrap(F3VirtualMachine f3vm, ArrayType at) { return (at == null)? null : f3vm.arrayType(at); }
public F3ArrayType(F3VirtualMachine f3vm, ArrayType underlying) { super(f3vm, underlying); }
private void processArrayCellWrite(final Location location, final StackFrame frame, final IObjectContour oc) { if (!manager().generateArrayEvents() || oc == null) { return; } final Object jvm = owner.getJVM(); if (jvm != null) { final VirtualMachine vm = (VirtualMachine) jvm; // traverse loaded classes to find the array for (final Object c : vm.allClasses()) { // skip non-arrays if (!(c instanceof ArrayType)) { continue; } // array type final ArrayType refType = (ArrayType) c; final ITypeNodeRef type = staticModelFactory().lookupTypeNode(refType.signature()); // skip if not the same type as the array contour if (type == null || type.node() != oc.schema()) { continue; } // create all instances but do not assign field values for (final Object o : refType.instances(0)) { if (o instanceof ArrayReference) { final ArrayReference ar = (ArrayReference) o; if (ar.uniqueID() == oc.oid()) { if (visitArrayCells(location, frame, ar, oc)) { System.err .println("Processed cell assginment to array: returned from method or invisible local variable."); } } } } } } }