/// <summary>
        /// Initializes the this instance with the specified memory location ranges.
        /// </summary>
        /// <param name="ranges">The memory location ranges.</param>
        protected void Initialize(MemoryLocation[] ranges)
        {
            int newEnd = 0;

            for (int i = 1; i < ranges.Length; i++)
            {
                if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd)
                {
                    ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd;
                }
                else
                {
                    ranges[++newEnd] = ranges[i];
                }
            }
            newEnd++;
            Array.Resize(ref ranges, newEnd);

            this.ranges = ranges;
            finder      = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion {
                BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd
            }).ToList());
        }
        public DumpFileMemoryReader(string dumpFilePath)
        {
            bool dispose = true;
            FileStream fileStream = null;
            MemoryMappedFile memoryMappedFile = null;
            MemoryMappedViewStream stream = null;

            try
            {
                fileStream = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read);
                memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false);
                stream = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read);

                stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer);
                IntPtr streamPointer = IntPtr.Zero;
                uint streamSize = 0;
                MINIDUMP_DIRECTORY directory = new MINIDUMP_DIRECTORY();

                if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize))
                    throw new Exception("Unable to read mini dump stream");

                var data = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST));
                ulong lastEnd = data.BaseRva;

                ranges = new MemoryLocation[data.NumberOfMemoryRanges];
                for (int i = 0; i < ranges.Length; i++)
                {
                    var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64));
                    ranges[i] = new MemoryLocation()
                    {
                        MemoryStart = descriptor.StartOfMemoryRange,
                        MemoryEnd = descriptor.StartOfMemoryRange + descriptor.DataSize,
                        FilePosition = lastEnd,
                    };
                    lastEnd += descriptor.DataSize;
                }

                int newEnd = 0;
                for (int i = 1; i < ranges.Length; i++)
                    if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd)
                        ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd;
                    else
                        ranges[++newEnd] = ranges[i];
                newEnd++;
                Array.Resize(ref ranges, newEnd);
                finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion { BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd }).ToArray());
                dispose = false;
            }
            finally
            {
                if (dispose)
                {
                    stream.SafeMemoryMappedViewHandle.ReleasePointer();
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    if (memoryMappedFile != null)
                    {
                        memoryMappedFile.Dispose();
                    }

                    if (fileStream != null)
                    {
                        fileStream.Dispose();
                    }
                }
                else
                {
                    this.fileStream = fileStream;
                    this.stream = stream;
                    this.memoryMappedFile = memoryMappedFile;
                }
            }
        }
Example #3
0
        public DumpFileMemoryReader(string dumpFilePath)
        {
            bool                   dispose          = true;
            FileStream             fileStream       = null;
            MemoryMappedFile       memoryMappedFile = null;
            MemoryMappedViewStream stream           = null;

            try
            {
                fileStream       = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read);
                memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false);
                stream           = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read);

                stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer);
                IntPtr             streamPointer = IntPtr.Zero;
                uint               streamSize    = 0;
                MINIDUMP_DIRECTORY directory     = new MINIDUMP_DIRECTORY();

                if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize))
                {
                    throw new Exception("Unable to read mini dump stream");
                }

                var   data    = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST));
                ulong lastEnd = data.BaseRva;

                ranges = new MemoryLocation[data.NumberOfMemoryRanges];
                for (int i = 0; i < ranges.Length; i++)
                {
                    var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64));
                    ranges[i] = new MemoryLocation()
                    {
                        MemoryStart  = descriptor.StartOfMemoryRange,
                        MemoryEnd    = descriptor.StartOfMemoryRange + descriptor.DataSize,
                        FilePosition = lastEnd,
                    };
                    lastEnd += descriptor.DataSize;
                }

                int newEnd = 0;
                for (int i = 1; i < ranges.Length; i++)
                {
                    if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd)
                    {
                        ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd;
                    }
                    else
                    {
                        ranges[++newEnd] = ranges[i];
                    }
                }
                newEnd++;
                Array.Resize(ref ranges, newEnd);
                finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion {
                    BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd
                }).ToArray());
                dispose = false;
            }
            finally
            {
                if (dispose)
                {
                    stream.SafeMemoryMappedViewHandle.ReleasePointer();
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    if (memoryMappedFile != null)
                    {
                        memoryMappedFile.Dispose();
                    }

                    if (fileStream != null)
                    {
                        fileStream.Dispose();
                    }
                }
                else
                {
                    this.fileStream       = fileStream;
                    this.stream           = stream;
                    this.memoryMappedFile = memoryMappedFile;
                }
            }
        }