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)));
 }
Пример #3
0
            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);
            }