public static bool IsInvalidOffset(long size, long offset) { return(ExpressionParser.IsInvalidAddressDifference(offset) || offset < 0 || offset >= size); }
public override int LoadSize(Debugger debugger, string name) { return(ExpressionParser.LoadSize(debugger, SizeStr(name))); }
public override ExpressionDrawer.IDrawable Load(MemoryReader mreader, Debugger debugger, string name, string type, LoadCallback callback) { // NOTE: If the image is not created at the point of debugging, so the variable is // uninitialized, the size may be out of bounds of int32 range. In this case the // exception is thrown here and this is ok. However if there is some garbage in // memory random size could be loaded here. Then also the memory probably points // to some random place in memory (maybe protected?) so the result will probably // be another exception which is fine or an image containing noise from memory. int width = ExpressionParser.LoadSize(debugger, name + "._view._dimensions.x"); int height = ExpressionParser.LoadSize(debugger, name + "._view._dimensions.y"); if (width < 1 || height < 1) { return(null); } string pixelType, isPlanarStr; if (!Util.Tparams(type, out pixelType, out isPlanarStr)) { return(null); } string pixelId = Util.TypeId(pixelType); if (pixelId != "boost::gil::pixel") { return(null); } bool isPlanar = (isPlanarStr == "1"); string channelValueType, layoutType; if (!Util.Tparams(pixelType, out channelValueType, out layoutType)) { return(null); } string layoutId = Util.TypeId(layoutType); if (layoutId != "boost::gil::layout") { return(null); } string colorSpaceType, channelMappingType; if (!Util.Tparams(layoutType, out colorSpaceType, out channelMappingType)) { return(null); } ChannelValueKind channelValueKind = ChannelValueKind.Unknown; int channelValueSize = 0; ParseChannelValue(debugger, channelValueType, out channelValueKind, out channelValueSize); if (channelValueKind == ChannelValueKind.Unknown || channelValueSize == 0) { return(null); } string colorSpaceId = Util.TypeId(colorSpaceType); ColorSpace colorSpace = ParseColorSpace(colorSpaceType); int colorSpaceSize = ColorSpaceSize(colorSpace); if (colorSpace == ColorSpace.Unknown || colorSpaceSize == 0) { return(null); } Layout layout = ParseChannelMapping(colorSpace, channelMappingType); if (layout == Layout.Unknown) { return(null); } if (channelValueSize != 1 && channelValueSize != 2 && channelValueSize != 4 && channelValueSize != 8) { return(null); } // TODO: size_t? ulong? int bytesCount = width * height * colorSpaceSize * channelValueSize; byte[] memory = new byte[bytesCount]; bool isLoaded = false; if (mreader != null) { ulong address = ExpressionParser.GetValueAddress(debugger, name + "._memory[0]"); if (address == 0) { return(null); } isLoaded = mreader.ReadBytes(address, memory); } if (!isLoaded) { // Parsing the memory byte by byte may take very long time // even for small images. So don't do it. return(null); } LayoutMapper layoutMapper = GetLayoutMapper(layout); if (layoutMapper == null) { return(null); } // Use Pixel format native to Gil Image? System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height); for (int j = 0; j < height; ++j) { for (int i = 0; i < width; ++i) { int pixelIndex = (j * width + i); // The raw bytes are converted into channel values pixel by pixel. // It could be more efficient to convert all channel values at once first // and only create pixels from array of channels in this loop. // Another thing is that when channels are always converted to byte // the information is lost. This information could be used during potential // conversion in GetColor() below (cmyk->rgb). Channels could be returned // as float[]. In practice the eye will probably not notice the difference. byte[] channels = isPlanar ? GetChannelsPlanar(memory, pixelIndex, channelValueKind, channelValueSize, colorSpaceSize) : GetChannelsInterleaved(memory, pixelIndex, channelValueKind, channelValueSize, colorSpaceSize); if (channels == null) { return(null); } System.Drawing.Color c = layoutMapper.GetColor(channels); bmp.SetPixel(i, j, c); // TODO: Checked per pixel. Too often? // But it's the same for geometries (ForEachMemoryBlock). if (!callback()) { return(null); } } } return(new ExpressionDrawer.Image(bmp)); }
public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger, string name, string type, MemoryReader.Converter <double> elementConverter, MemoryBlockPredicate memoryBlockPredicate) { int size = LoadSize(debugger, name); if (size <= 0) { return(true); } string headName = HeadStr(name); string leftName = headName + "->_Left"; string rightName = headName + "->_Right"; string isNilName = headName + "->_Isnil"; string valName = headName + "->_Myval"; TypeInfo headInfo = new TypeInfo(debugger, headName); if (!headInfo.IsValid) { return(false); } MemoryReader.ValueConverter <byte, byte> boolConverter = new MemoryReader.ValueConverter <byte, byte>(); MemoryReader.ValueConverter <ulong> ptrConverter = mreader.GetPointerConverter(headInfo.Type, headInfo.Size); if (ptrConverter == null) { return(false); } long leftDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + headName + ")", leftName); long rightDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + headName + ")", rightName); long isNilDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + headName + ")", isNilName); long valDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + headName + ")", valName); if (ExpressionParser.IsInvalidAddressDifference(leftDiff) || ExpressionParser.IsInvalidAddressDifference(rightDiff) || ExpressionParser.IsInvalidAddressDifference(isNilDiff) || ExpressionParser.IsInvalidAddressDifference(valDiff) || leftDiff < 0 || rightDiff < 0 || isNilDiff < 0 || valDiff < 0) { return(false); } ulong address = ExpressionParser.GetValueAddress(debugger, headName); if (address == 0) { return(false); } ulong[] headAddr = new ulong[1]; if (!mreader.Read(address, headAddr, ptrConverter)) { return(false); } return(ForEachMemoryBlockRecursive(mreader, elementConverter, memoryBlockPredicate, boolConverter, ptrConverter, headAddr[0], leftDiff, rightDiff, isNilDiff, valDiff)); }
public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger, string name, string type, MemoryReader.Converter <double> elementConverter, MemoryBlockPredicate memoryBlockPredicate) { int size = LoadSize(debugger, name); if (size <= 0) { return(true); } string nextName = HeadStr(name) + "->_Next"; string nextNextName = HeadStr(name) + "->_Next->_Next"; string nextValName = HeadStr(name) + "->_Next->_Myval"; TypeInfo nextInfo = new TypeInfo(debugger, nextName); if (!nextInfo.IsValid) { return(false); } MemoryReader.ValueConverter <ulong> nextConverter = mreader.GetPointerConverter(nextInfo.Type, nextInfo.Size); if (nextConverter == null) { return(false); } long nextDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + nextName + ")", nextNextName); long valDiff = ExpressionParser.GetAddressDifference(debugger, "(*" + nextName + ")", nextValName); if (ExpressionParser.IsInvalidAddressDifference(nextDiff) || ExpressionParser.IsInvalidAddressDifference(valDiff) || nextDiff < 0 || valDiff < 0) { return(false); } ulong[] nextTmp = new ulong[1]; ulong next = 0; for (int i = 0; i < size; ++i) { ulong address = 0; if (next == 0) { address = ExpressionParser.GetValueAddress(debugger, nextName); if (address == 0) { return(false); } } else { address = next + (ulong)nextDiff; } if (!mreader.Read(address, nextTmp, nextConverter)) { return(false); } next = nextTmp[0]; double[] values = new double[elementConverter.ValueCount()]; if (!mreader.Read(next + (ulong)valDiff, values, elementConverter)) { return(false); } if (!memoryBlockPredicate(values)) { return(false); } } return(true); }
public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger, string name, string type, MemoryReader.Converter <double> elementConverter, MemoryBlockPredicate memoryBlockPredicate) { int size = LoadSize(debugger, name); if (size == 0) { return(true); } // Map size int mapSize = 0; if (!ExpressionParser.TryLoadInt(debugger, MapSizeStr(name), out mapSize)) { return(false); } VariableInfo mapInfo = new VariableInfo(debugger, MapStr(name) + "[0]"); if (!mapInfo.IsValid) { return(false); } // Map - array of pointers ulong[] pointers = new ulong[mapSize]; if (!mreader.ReadPointerArray(mapInfo.Address, mapInfo.Type, mapInfo.Size, pointers)) { return(false); } // Block size int dequeSize = 0; if (!ExpressionParser.TryLoadInt(debugger, "((int)" + name + "._EEN_DS)", out dequeSize)) { return(false); } // Offset int offset = 0; if (!ExpressionParser.TryLoadInt(debugger, OffsetStr(name), out offset)) { return(false); } // Initial indexes int firstBlock = ((0 + offset) / dequeSize) % mapSize; int firstElement = (0 + offset) % dequeSize; int backBlock = (((size - 1) + offset) / dequeSize) % mapSize; int backElement = ((size - 1) + offset) % dequeSize; int blocksCount = firstBlock <= backBlock ? backBlock - firstBlock + 1 : mapSize - firstBlock + backBlock + 1; int globalIndex = 0; for (int i = 0; i < blocksCount; ++i) { int blockIndex = (firstBlock + i) % mapSize; ulong address = pointers[blockIndex]; if (address != 0) // just in case { int elemIndex = (i == 0) ? firstElement : 0; int blockSize = dequeSize - elemIndex; if (i == blocksCount - 1) // last block { blockSize -= dequeSize - (backElement + 1); } if (blockSize > 0) // just in case { MemoryReader.ArrayConverter <double> arrayConverter = new MemoryReader.ArrayConverter <double>(elementConverter, blockSize); if (arrayConverter == null) { return(false); } int valuesCount = elementConverter.ValueCount() * blockSize; ulong firstAddress = address + (ulong)(elemIndex * elementConverter.ByteSize()); double[] values = new double[valuesCount]; if (!mreader.Read(firstAddress, values, arrayConverter)) { return(false); } if (!memoryBlockPredicate(values)) { return(false); } globalIndex += blockSize; } } } return(true); }
public override int LoadSize(Debugger debugger, string name) { return(ExpressionParser.LoadSize(debugger, name + ".m_size")); }
public override bool ForEachMemoryBlock(MemoryReader mreader, Debugger debugger, string name, string type, MemoryReader.Converter <double> elementConverter, MemoryBlockPredicate memoryBlockPredicate) { int size = LoadSize(debugger, name); if (size <= 0) { return(true); } // TODO: All of the debugger-related things should be done // in Initialize(). // TODO: Handle non-value types, // It is not clear for now where the distinction should be made // in the container or outside. When non-value types are stored // the container effectively stores pointers to objects. // So whether or not it's a pointer-container is defined by the // element type in C# and by the container in C++. string elementType = debugger.GetExpression(name + ".head.item").Type; Expression isValueTypeExpr = debugger.GetExpression("typeof(" + elementType + ").IsValueType"); if (!isValueTypeExpr.IsValidValue || isValueTypeExpr.Value != "true") { return(false); } //string headPointerPointerName = "(void*)&(" + name + ".head)"; //(void*)IntPtr* string headPointerName = "(void*)*(&(" + name + ".head))"; // (void*)IntPtr string nextPointerPointerName = "(void*)&(" + name + ".head.next)"; //(void*)IntPtr* string nextPointerName = "(void*)*(&(" + name + ".head.next))"; // (void*)IntPtr string valPointerName = "(void*)&(" + name + ".head.item)"; // (void*)IntPtr* or (void*)ValueType* TypeInfo nextPointerInfo = new TypeInfo(debugger, nextPointerPointerName); TypeInfo nextInfo = new TypeInfo(debugger, nextPointerName); if (!nextPointerInfo.IsValid || !nextInfo.IsValid) { return(false); } MemoryReader.ValueConverter <ulong> pointerConverter = mreader.GetPointerConverter(nextPointerInfo.Type, nextPointerInfo.Size); if (pointerConverter == null) { return(false); } long nextDiff = ExpressionParser.GetPointerDifference(debugger, headPointerName, nextPointerPointerName); long valDiff = ExpressionParser.GetPointerDifference(debugger, headPointerName, valPointerName); if (ExpressionParser.IsInvalidAddressDifference(nextDiff) || ExpressionParser.IsInvalidAddressDifference(valDiff) || nextDiff < 0 || valDiff < 0) { return(false); } ulong address = ExpressionParser.GetPointer(debugger, headPointerName); if (address == 0) { return(false); } for (int i = 0; i < size; ++i) { double[] values = new double[elementConverter.ValueCount()]; if (!mreader.Read(address + (ulong)valDiff, values, elementConverter)) { return(false); } if (!memoryBlockPredicate(values)) { return(false); } ulong[] nextTmp = new ulong[1]; if (!mreader.Read(address + (ulong)nextDiff, nextTmp, pointerConverter)) { return(false); } address = nextTmp[0]; } return(true); }