public ObjectValue[] GetArrayChildren(ObjectCacheNode cacheNode,ObjectPath arrayPath, int index, int elementsToDisplay, EvaluationOptions options) { var t = cacheNode.NodeType as ArrayType; var elementType = t.ValueType; var sizeOfElement = SizeOf (elementType); ulong firstItemPointer; if (cacheNode is SubArrayCacheNode) { var sac = cacheNode as SubArrayCacheNode; firstItemPointer = sac.firstItem; elementsToDisplay = Math.Min (sac.length, index + elementsToDisplay) - index; } else { var header = Memory.ReadDArrayHeader (cacheNode.addressExpression); firstItemPointer = header.FirstItem.ToUInt64 (); elementsToDisplay = Math.Min (header.Length, index + elementsToDisplay) - index; } byte[] rawArrayContent; var startAddress = firstItemPointer + (ulong)(index * sizeOfElement); Memory.Read (startAddress.ToString (), sizeOfElement * elementsToDisplay, out rawArrayContent); var children = new ObjectValue[elementsToDisplay]; ObjectPath item; var elementTypeToken = elementType is PrimitiveType ? (elementType as PrimitiveType).TypeToken : DTokens.INVALID; if (elementTypeToken != DTokens.INVALID) { var valFunc = DGdbTools.GetValueFunction (elementTypeToken); var elementTypeString = elementType.ToCode (); var hex = DisplayAsHex; for (uint i = 0; i < elementsToDisplay; i++) { var valStr = valFunc (rawArrayContent, (int)(i * sizeOfElement), hex); item = arrayPath.Append ((index + i).ToString ()); children [i] = ObjectValue.CreatePrimitive (ValueSource, item, elementTypeString, new EvaluationResult (valStr), ObjectValueFlags.ArrayElement); } } else if (elementType is ArrayType) { var elementArrayType = elementType as ArrayType; for (var i = elementsToDisplay - 1; i >= 0; i--){ item = arrayPath.Append ((index + i).ToString ()); try{ int subArrayLength; ulong subArrayFirstPointer; ExamArrayInfo (rawArrayContent, i * sizeOfElement, out subArrayLength, out subArrayFirstPointer); children [i] = EvaluateArray (subArrayLength, subArrayFirstPointer, elementArrayType, ObjectValueFlags.ArrayElement, item); cacheNode.Set(new SubArrayCacheNode(item.LastName, elementArrayType, subArrayFirstPointer, subArrayLength)); }catch(Exception ex) { Ide.MessageService.ShowException (ex); } } } else if (elementType is PointerType || elementType is InterfaceType || elementType is ClassType) { for (int i = 0; i < elementsToDisplay; i++) { item = arrayPath.Append ((index + i).ToString ()); long elementPointer; if (sizeOfElement == 4) elementPointer = BitConverter.ToInt32 (rawArrayContent, i * 4); else elementPointer = BitConverter.ToInt64 (rawArrayContent, i * 8); children [i] = EvaluateVariable (elementPointer.ToString (), ref elementType, ObjectValueFlags.ArrayElement, item); cacheNode.Set(new ObjectCacheNode(item.LastName, elementType, (elementPointer+i*sizeOfElement).ToString())); } } else if (elementType is StructType/* || elementType is UnionType*/) { // Get struct size or perhaps just get the struct meta information from gdb //return ObjectValue.CreateNotSupported (ValueSource, path, t.ToCode (), "Struct/Union arrays can't be examined yet", flags); } return children; }
public void Set(ObjectCacheNode ch) { if (ch == null || ch is ObjectRootCacheNode || ch == this) throw new ArgumentException("ch and the name must be set and must not be the root node"); children [ch.Name] = ch; }
public ObjectValue[] GetClassInstanceChildren(ObjectCacheNode cacheNode,ObjectPath classPath, EvaluationOptions options) { bool isStruct = cacheNode.NodeType is StructType || cacheNode.NodeType is UnionType; if (!isStruct && !(cacheNode.NodeType is ClassType)) throw new ArgumentException ("Can only handle structs, unions and classes!"); var objectMembers = new List<ObjectValue> (); int objectSize; var members = GetMembersWithOffsets (cacheNode.NodeType as TemplateIntermediateType, out objectSize); // read in the object bytes -- The length of an object can be read dynamically and thus the primary range of bytes that contain object properties. byte[] bytes; if (isStruct) { Memory.Read (MemoryExamination.BuildAddressExpression(cacheNode.addressExpression, "&({0})"), objectSize, out bytes); } else bytes = Memory.ReadObjectBytes (cacheNode.addressExpression); foreach (var kv in members) { var member = kv.Item1; var currentOffset = kv.Item2; var memberType = member.Base; while (memberType is TemplateParameterSymbol || memberType is AliasedType) memberType = (memberType as DSymbol).Base; var memberFlags = BuildObjectValueFlags (member) | ObjectValueFlags.Field; var memberPath = classPath.Append (member.Name); try { if (memberType is PrimitiveType) { objectMembers.Add (EvaluatePrimitive (bytes, currentOffset, memberType as PrimitiveType, memberFlags, memberPath)); } else if (memberType is ArrayType) { objectMembers.Add (EvaluateArray (bytes, currentOffset, memberType as ArrayType, memberFlags, memberPath)); } else if (memberType is PointerType || memberType is InterfaceType || memberType is ClassType) { long ptr; if (DGdbSession.Is64Bit) ptr = BitConverter.ToInt64 (bytes, currentOffset); else ptr = BitConverter.ToInt32 (bytes, currentOffset); if (ptr < 1) objectMembers.Add (ObjectValue.CreateNullObject (ValueSource, memberPath, memberType.ToCode(), memberFlags)); else objectMembers.Add (EvaluateVariable (ptr.ToString (),ref memberType, memberFlags, memberPath)); } else if(memberType is StructType) objectMembers.Add(ObjectValue.CreateObject(ValueSource, memberPath, memberType.ToCode(), memberType.ToString(), memberFlags, null)); } catch (Exception ex) { Backtrace.DSession.LogWriter (false, "Error in GetClassInstanceChildren(memberPath="+memberPath.ToString()+"): " + ex.Message+"\n"); } // TODO: use alignof property instead of constant // Create access expression for field inside the object. string addressExpression; if(isStruct) { addressExpression = MemoryExamination.EnforceReadRawExpression+"((void*)"+MemoryExamination.BuildAddressExpression(cacheNode.addressExpression, "&({0})")+ "+"+currentOffset+")"; } else addressExpression = MemoryExamination.EnforceReadRawExpression+"((void*)"+MemoryExamination.BuildAddressExpression(cacheNode.addressExpression) + "+" + currentOffset+")"; cacheNode.Set (new ObjectCacheNode (member.Name, memberType, addressExpression)); } return objectMembers.ToArray (); }