Пример #1
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.
                ulong dataStart = ExpressionParser.GetPointer(debugger, name + ".DataStart");
                ulong dataEnd   = ExpressionParser.GetPointer(debugger, name + ".DataEnd");
                ulong length    = dataEnd - dataStart;
                int   cols      = ExpressionParser.LoadSize(debugger, name + ".Cols");
                int   rows      = ExpressionParser.LoadSize(debugger, name + ".Rows");

                EnvDTE.Expression exp = debugger.GetExpression("(int)(" + name + ".Type())");

                MatType mType = MatType.CV_8UC1;

                if (exp.IsValidValue)
                {
                    mType = (MatType)int.Parse(exp.Value);
                }

                byte[] memory   = new byte[length];
                bool   isLoaded = false;

                if (mreader != null)
                {
                    ulong address = ExpressionParser.GetValueAddress(debugger, name + ".DataPointer[0]");
                    if (address == 0)
                    {
                        return(null);
                    }

                    isLoaded = mreader.ReadBytes(address, memory);
                }

                var    pixelFormat = MatTypeToPixelFormat(mType);
                Bitmap bmp         = new Bitmap(
                    cols,
                    rows,
                    pixelFormat);

                BitmapData data = bmp.LockBits(
                    new Rectangle(System.Drawing.Point.Empty, bmp.Size),
                    ImageLockMode.WriteOnly,
                    pixelFormat);

                Marshal.Copy(memory, 0, data.Scan0, (int)length);

                bmp.UnlockBits(data);

                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);
                }

                // 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);
            }