コード例 #1
0
        /// <summary>
        /// Construct a memory analyzer
        /// </summary>
        /// <param name="heap">First Heap (mandatory)</param>
        /// <param name="heap2">Second Heap which can be null. </param>
        /// <param name="bLiveOnly">If true only rooted objects are considered. This takes longer to execute but is more accurate. Otherwise temp objects which have not yet been collected also show up.</param>
        /// <param name="bGetVMMapData">If true then from running processes the VMMap information is read.</param>
        /// <param name="info">Target process pid and/or dump files names.</param>
        /// <param name="displayunit">Units in which bytes should be displayed</param>
        /// <param name="timeFormat">.NET Format string for time and date. If value is Invariant then the invariant culture is used to format.</param>
        /// <param name="context">Optional context column which is printed to each output line when CSV output is enabled to e.g. dump the memory for test run nr 1, 2, 3, which gives nice metric in Excel later.</param>
        public MemAnalyzer(ClrHeap heap, ClrHeap heap2, bool bLiveOnly, bool bGetVMMapData, TargetInformation info, DisplayUnit displayunit = DisplayUnit.MB, string timeFormat = null, string context = null)
            : base(heap, heap2, bLiveOnly, displayunit)
        {
            GetVMMapData = bGetVMMapData;
            TargetInfo   = info;
            ProcessName  = TargetInfo.IsLiveProcess? TargetInformation.GetProcessName(TargetInfo.Pid1) : "";
            CmdLine      = TargetInfo.IsLiveProcess ? TargetInformation.GetProcessCmdLine(TargetInfo.Pid1) : "";
            DateTime now = TargetInfo.CurrentTimeOrDumpCreationDate;

            TimeAndOrDate = TargetInfo.ExternalTime ?? (timeFormat == "Invariant" ? now.ToString(CultureInfo.InvariantCulture) : now.ToString(timeFormat));
            Context       = context;
        }
コード例 #2
0
        /// <summary>
        /// Get VMMap data from process
        /// </summary>
        /// <param name="bFirstProcess"></param>
        /// <param name="targetInfo"></param>
        /// <param name="heap"></param>
        /// <returns></returns>
        private static VMMapData GetVMMapDataFromProcess(bool bFirstProcess, TargetInformation targetInfo, ClrHeap heap)
        {
            int       pid  = bFirstProcess ? targetInfo.Pid1 : targetInfo.Pid2;
            VMMapData data = new VMMapData();

            if (pid != 0)
            {
                // we must first detach CLRMD or VMMAp will block at least in x64 in the target process to get heap information.
                // Play safe and do not try this asynchronously.
                heap?.Runtime?.DataTarget?.Dispose();
                data = StartVMMap(pid, null);
            }
            else
            {
                string existingVMMapFile = bFirstProcess ? targetInfo.DumpVMMapFile1 : targetInfo.DumpVMMapFile2;
                if (existingVMMapFile != null)
                {
                    data = StartVMMap(0, existingVMMapFile);
                }
            }

            return(data);
        }
コード例 #3
0
ファイル: DumpCreator.cs プロジェクト: gavz/MemAnalyzer
        /// <summary>
        /// Create a memory dump with procdump and then call VMMap to dump the memory constituents into a csv file besides the dump.
        /// </summary>
        /// <param name="procdumpArgs"></param>
        /// <returns></returns>
        public string Dump(string[] procdumpArgs)
        {
            string args = GetProcDumpArgs(procdumpArgs);

            ProcessStartInfo info = new ProcessStartInfo(ProcDumpExe, $"-accepteula {args}")
            {
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                UseShellExecute        = false,
            };

            var           p = Process.Start(info);
            string        line;
            string        dumpFileName  = null;
            List <string> lines         = new List <string>();
            bool          procDumpError = false;

            while ((line = p.StandardOutput.ReadLine()) != null)
            {
                lines.Add(line);
                if (ShowOutput)
                {
                    Console.WriteLine(line);
                }

                if (line.Contains("Error creating dump file"))
                {
                    procDumpError = true;
                }

                if (dumpFileName == null && procDumpError == false)
                {
                    dumpFileName = GetDumpFileName(line);
                }
            }

            if (dumpFileName == null)
            {
                if (!ShowOutput)
                {
                    lines.ForEach(Console.WriteLine);
                }
                Console.WriteLine($"Error: Could not create dump file with procdump args: {args}!");
                return(null);
            }
            else
            {
                Console.WriteLine($"Dump file {dumpFileName} created.");
            }


            int pid = FindPidInProcDumpArgs(procdumpArgs, out string exeName);

            if (pid == 0)
            {
                ProcessFilter filter = new ProcessFilter(exeName ?? "");
                pid = filter.GetMatchingPids().FirstOrDefault();
            }

            if (pid != 0)
            {
                string outFile = TargetInformation.GetAssociatedVMMapFile(dumpFileName);
                VMMap.SaveVMmapDataToFile(pid, outFile);
            }
            else
            {
                Console.WriteLine($"Error: Could not create find process id of dumped process {exeName}. No VMMap information is saved. ");
            }

            if (VerifyDump && !CanLoadDump(dumpFileName))
            {
                Console.WriteLine($"Error: Dump file cannot be parsed with MemAnalyzer. Managed Heap might be in an inconsistent state.");
                dumpFileName = null;
            }


            return(dumpFileName);
        }