示例#1
0
 internal ReportForm([NotNull] MainForm f)
 {
     this.f         = f;
     this.graphtype = f.graphtype;
     if (!f.noUI)
     {
         InitializeComponent();
     }
     try
     {
         buildReports();
     }
     catch (Exception e)
     {
         throw new Exception(e.Message + "\n");
     }
 }
示例#2
0
		internal ReportForm(MainForm f)
		{
			this.f = f;
			this.runaswindow  = f.runaswindow;
			this.graphtype = f.graphtype;
			if(	runaswindow)
			{
				InitializeComponent();
			}
			try
			{
				buildReports();
			}
			catch(Exception e)
			{
				throw new Exception(e.Message + "\n");
			}
		}
示例#3
0
        private void ShowUsage()
        {
            graphtype = Graph.GraphType.Invalid;
            String s = "";
            s += String.Format("Usage: {0} -attach PID [-o logName] [-t timeoutInMiliseconds]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -attach PID      \t- attaches to the target process\r\n";
            s += "  -o logName       \t- file to write the resulting profile log to\r\n";
            s += "  -t timeout       \t- max time in miliseconds to wait for the attach to succeed\r\n"; 
            s += "or\r\n";
            s += String.Format("{0} -detach PID\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -detach PID      \t- detaches from the target process (use -attach first)\r\n";
            s += "or\r\n";
            s += String.Format("{0} -dumpheap PID\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -dumpheap PID    \t- triggers a GC and dumps the GC heap in the target process (use -attach first)\r\n";
            s += "or\r\n";
            s += String.Format("{0} -o logName [-na] [-nc] -[np] [-target V4DesktopCLR|V4CoreCLR|V2DesktopCLR] -u URL\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -u URL\t- URL to profile (must go at the end)\r\n";
            s += "  -o logName\t- file to write the resulting profile log to\r\n";
            s += "  -na\t\t- don't record allocations\r\n";
            s += "  -nc\t\t- don't record calls\r\n";
            s += "  -np\t\t- start with profiling active off\r\n";
            s += "  -target V4DesktopCLR|V4CoreCLR|V2DesktopCLR\t- specify the target CLR runtime to be profiled (V4DesktopCLR is the default choice)\r\n";
            s += "or\r\n";
            s += String.Format("{0} [-o logName] [-na] [-nc] -[np] [-target V4DesktopCLR|V4CoreCLR|V2DesktopCLR] -p exeName [args]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -p exeName args\t- application to profile and its arguments (must go at the end)\r\n";
            s += "  -o logName\t- file to write the resulting profile log to\r\n";
            s += "  -na\t\t- don't record allocations\r\n";
            s += "  -nc\t\t- don't record calls\r\n";
            s += "  -np\t\t- start with profiling active off\r\n";
            s += "  -target V4DesktopCLR|V4CoreCLR|V2DesktopCLR\t- specify the target CLR runtime to be profiled (V4DesktopCLR is the default choice)\r\n";
            s += "or\r\n";
            s += String.Format("{0} -a -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -a               \t - asks for an allocation report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report allocations after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report allocations before this log file comment\r\n";
            s += "or\r\n";
            s += String.Format("{0} -r -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -r               \t - asks for a relocation report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report relocations after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report relocations before this log file comment\r\n";
            s += "or\r\n";
            s += String.Format("{0} -s -l logName [-b <start marker>] [-e <end marker>] [-t <time marker]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -s               \t - asks for a surviving objects report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report objects allocated after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report objects allocated before this log file comment\r\n";
            s += "  -t <time marker> \t - report survivors at this log file comment\r\n";
            s += "or\r\n";
            s += String.Format("{0} -[c]f -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -[c]f            \t - asks for a [critical] finalizer report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report finalizers queued after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report finalizers queued before this log file comment\r\n";
            s += "or\r\n";
            s += String.Format("{0} -sd -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -sd              \t - asks for a survivor difference report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - first instant in time to gather survivors\r\n";
            s += "  -e <end marker>  \t - second instant in time to compare survivorship agains\r\n";
            s += "or\r\n";
            s += String.Format("{0} -h -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -h               \t - asks for a heap dump report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report heap dumps after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report heap dumps before this log file comment\r\n";
            s += "                   \t - (giving only -b reports the first heap after the log file comment)\r\n";
            s += "or\r\n";
            s += String.Format("{0} -c -l logName\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "  -c               \t - asks for a list of the comments in the input log file\r\n";
            s += "or\r\n";
            s += String.Format("{0} -lr -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "Where\r\n";
            s += "  -lr              \t - asks for a leak report\r\n";
            s += "  -l logName       \t - names the input log file\r\n";
            s += "  -b <start marker>\t - only report allocations after this log file comment\r\n";
            s += "  -e <end marker>  \t - only report allocations before this log file comment\r\n";
            s += "or\r\n";
            s += String.Format("{0} -diff [-lo OldlogName -ln NewlogName] [-ld DifflogName][-w]\r\n", Path.GetFileName(Application.ExecutablePath));
            s += "Where\r\n";
            s += "  -diff            \t- asks for a difference report\r\n";
            s += "  -lo logName      \t- old resulting profile log file\r\n";
            s += "  -ln logName      \t- new resulting profile log file\r\n";
            s += "  -ld logName      \t- diff result of old and new profile log file\r\n";
            s += "  -w               \t- run as window (otherwise textual report)\r\n";

            if (noUI)
            {
                Console.Write(s);
            }
            else
            {
                HelpForm helpForm = new HelpForm();
                helpForm.helpText.Text = s;
                helpForm.ShowDialog();
            }
            return;
        }
示例#4
0
        private void viewComparisonMenuItem_Click(object sender, System.EventArgs e)
        {
            currlogFileName = this.logFileName;

            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.FileName = "*.log";
            openFileDialog1.Filter = "Allocation Logs | *.log";
            if (openFileDialog1.ShowDialog() == DialogResult.OK && openFileDialog1.CheckFileExists)
            {
                prevlogFileName = openFileDialog1.FileName;
            }
            this.noUI = false;
            graphtype = Graph.GraphType.AllocationGraph;
            try
            {
                ReportForm _MgrForm = new ReportForm(this);
                _MgrForm.Visible = true;
            }
            catch
            {
                /* errors already told user, so continue. */
            }
        }
示例#5
0
        public MainForm(string[] arguments)
        {
            int i;
            string logFileName = "";
            bool onlyCreateLog = false;
            processFileName = null;
            windowsStoreAppProfileeInfo = null;

            profileAllocations = profileCalls = profilingActive = true;

            //Check ProfilerOBJ.DLL exist first
            if (!File.Exists( getProfilerFullPath() ) )
            {
                ShowErrorMessage("Can not find '" + getProfilerFullPath() + "', please make sure ProfilerOBJ.dll exists at the same directory as CLRProfiler.exe.");
                Environment.ExitCode = 1;
                exitProgram = true;
                return;
            }

            #region arguments
            if (arguments.Length > 0)
            {
                int pid;

                Environment.ExitCode = 0;

                switch (arguments[0])
                {
                    case "-attach":
                    case "/attach":
                        exitProgram = true;
                        if ((pid = getPID(arguments)) == 0)
                        {
                            Environment.ExitCode = 1;
                            return;
                        }

                        for (int index = 2; index + 1 < arguments.Length; index = index+2)
                        { 
                            if (arguments[index] == "-o" || arguments[index] == "/o")
                            {
                                string fullPath = Path.GetFullPath(arguments[index+1]);
                                logDirectory = Path.GetDirectoryName(fullPath);
                                nameToUse = Path.GetFileName(fullPath);
                            }

                            if (arguments[index] == "-t" || arguments[index] == "/t")
                            {
                                maxWaitingTimeInMiliseconds = UInt32.Parse(arguments[index + 1]);
                                if (maxWaitingTimeInMiliseconds < 3000)
                                {
                                    maxWaitingTimeInMiliseconds = 3000;
                                    ShowErrorMessage("CLRProfiler must wait a minimum of 3000 milliseconds before it will time out while attaching to the application.");
                                }
                            }
                        }

                        if(logDirectory == null)
                        {
                            logDirectory = Directory.GetCurrentDirectory();
                        }
                        /* basic initialization stuff */
                        CreatePipe(@"\\.\pipe\OMV_PIPE", false, ref handshakingPipeHandle, ref handshakingPipe);
                        CreatePipe(@"\\.\pipe\OMV_LOGGING_PIPE", false, ref loggingPipeHandle, ref loggingPipe);
                        instance = this;

                        if (attachProfiler(pid, GetLogFullPath(pid)) )
                        {
                            Console.WriteLine("The logging data is saved at " + GetLogFullPath(pid) + ".");
                        }
                        else
                        {
                            Environment.ExitCode = 1;
                        }

                        ClearProfiledProcessInfo();
                        return;

                    case "-detach":
                    case "/detach":
                        exitProgram = true;

                        if ((pid = getPID(arguments)) == 0)
                        {
                            Environment.ExitCode = 1;
                            return;
                        }

                        if (!InitWindowsStoreAppProfileeInfoIfNecessary(pid))
                            return;

                        if (!isProfilerLoaded(pid))
                        {
                            Console.WriteLine("PID argument is not valid.");
                            Environment.ExitCode = 1;
                            return;
                        }

                        CreateEvents(pid);

                        SendDetachRequest();

                        Console.WriteLine("Detach is sucessfully requested.");
                        Console.WriteLine("It may take a while for CLRProfiler to be unloaded completely.  ");
                        Console.WriteLine("You may look for profiler detach event from the event log to determine if detach succeeds.");

                        ClearProfiledProcessInfo();
                        return;

                    case "-dumpheap":
                    case "/dumpheap":
                        exitProgram = true;

                        if ((pid = getPID(arguments)) == 0)
                        {
                            Environment.ExitCode = 1;
                            return;
                        }

                        if (!InitWindowsStoreAppProfileeInfoIfNecessary(pid))
                            return;

                        if (!isProfilerLoaded(pid))
                        {
                            Console.WriteLine("PID argument is not valid.");
                            Environment.ExitCode = 1;
                            return;
                        }

                        CreateEvents(pid);
                        forceGcCompletedEvent.Wait(1);
                        forceGcCompletedEvent.Reset();
                        forceGcEvent.Set();
                        Console.WriteLine(Path.GetFileName(Application.ExecutablePath) + " is waiting up to 10 minutes for target process to finish dumping the GC heap.");
                        if (forceGcCompletedEvent.Wait(10 * 60 * 1000))
                        {
                            forceGcCompletedEvent.Reset();
                            Console.WriteLine("A heap dump is appended in the log file.");
                        }
                        else
                        {
                            Console.WriteLine("There was no response from the target process.");
                            Environment.ExitCode = 1;
                        }
                        ClearEvents();
                        ClearProfiledProcessInfo();
                        return;
                }
            }
            #endregion arguments
            #region arguments2
            for (i = 0; i < arguments.Length && !onlyCreateLog; i++)
            {
                switch (arguments[i])
                {
                    case "-target":
                    case "/target":
                        string version = FetchArgument(arguments, ref i);

                        if (String.Compare(version, "V4DesktopCLR", true) == 0)
                            targetCLRVersion = CLRSKU.V4DesktopCLR;
                        else if (String.Compare(version, "V4CoreCLR", true) == 0)
                            targetCLRVersion = CLRSKU.V4CoreCLR;
                        else if (String.Compare(version, "V2DesktopCLR", true) == 0)
                            targetCLRVersion = CLRSKU.V2DesktopCLR;
                        else
                        {
                            CommandLineError("No matched target CLR version.");
                            help = true;
                        }
                        break;

                    case "-u":
                    case "/u":
                        if (logFileName == null)
                        {
                            CommandLineError("A log filename needs to be specified with -o beofre -u argument");
                            help = true;
                        }
                        else
                        {
                            profilingURL = FetchArgument(arguments, ref i);
                            if (profilingURL != null)
                                onlyCreateLog = true;
                        }
                        break;

                    case "-na":
                    case "/na":
                        profileAllocations = false;
                        break;

                    case "-nc":
                    case "/nc":
                        profileCalls = false;
                        break;

                    case "-np":
                    case "/np":
                        profilingActive = false;
                        break;

                    case "/ns":
                    case "-ns":
                        trackCallStacks = false;
                        break;

                    case "-o":
                    case "/o":
                        logFileName = FetchArgument(arguments, ref i);
                        break;

                    case "-p":
                    case "/p":
                        processFileName = FetchArgument(arguments, ref i);
                        if (processFileName != null)
                            onlyCreateLog = true;
                        break;

                    case "-diff":
                    case "/diff":
                        graphtype = Graph.GraphType.AllocationGraph;
                        break;

                    case "-lo":
                    case "/lo":
                        prevlogFileName = FetchArgument(arguments, ref i);
                        break;

                    case "-ln":
                    case "/ln":
                        currlogFileName = FetchArgument(arguments, ref i);
                        break;

                    case "-ld":
                    case "/ld":
                        difflogFileName = FetchArgument(arguments, ref i);
                        break;

                    case "-l":
                    case "/l":
                        logFileName = FetchArgument(arguments, ref i);
                        break;

                    case "-a":
                    case "/a":
                        reportKind = ReportKind.AllocationReport;
                        break;

                    case "-r":
                    case "/r":
                        reportKind = ReportKind.RelocationReport;
                        break;

                    case "-s":
                    case "/s":
                        reportKind = ReportKind.SurvivorReport;
                        break;

                    case "-sd":
                    case "/sd":
                        reportKind = ReportKind.SurvivorDifferenceReport;
                        break;

                    case "-h":
                    case "/h":
                        reportKind = ReportKind.HeapDumpReport;
                        break;

                    case "-lr":
                    case "/lr":
                        reportKind = ReportKind.LeakReport;
                        break;

                    case "-f":
                    case "/f":
                        reportKind = ReportKind.FinalizerReport;
                        break;

                    case "-cf":
                    case "/cf":
                        reportKind = ReportKind.CriticalFinalizerReport;
                        break;

                    case "-c":
                    case "/c":
                        reportKind = ReportKind.CommentReport;
                        break;

                    case "-b":
                    case "/b":
                        startMarker = FetchArgument(arguments, ref i);
                        break;

                    case "-e":
                    case "/e":
                        endMarker = FetchArgument(arguments, ref i);
                        break;

                    case "-t":
                    case "/t":
                        do
                        {
                            string[] newTimeMarker = new String[timeMarker.Length + 1];
                            for (int j = 0; j < timeMarker.Length; j++)
                                newTimeMarker[j] = timeMarker[j];
                            newTimeMarker[timeMarker.Length] = FetchArgument(arguments, ref i);
                            timeMarker = newTimeMarker;
                        }
                        while (i + 1 < arguments.Length && arguments[i + 1][0] != '-' && arguments[i + 1][0] != '/');
                        break;

                    case "-w":
                    case "/w":
                        this.noUI = false;
                        break;

                    case "-?":
                    case "/?":
                    case "-help":
                    case "/help":
                        help = true;
                        break;

                    case "-gc":
                    case "/gc":
                        gcOnLogFileComments = true;
                        break;

                    default:
                        if (arguments[i][0] == '-' || arguments[i][0] == '/')
                            CommandLineError("Unrecognized option {0}", arguments[i]);
                        else if (File.Exists(arguments[i]))
                            logFileName = arguments[i];
                        else
                            CommandLineError("Log file {0} not found", arguments[i]);
                        break;
                }
            }
            #endregion arguments2
            #region AllocationGraph
            if (graphtype == Graph.GraphType.AllocationGraph)
            {
                if (File.Exists(prevlogFileName) && File.Exists(currlogFileName))
                {
                    viewdiff = true;
                    return;
                }
                else
                {
                    String s = "";
                    if (!File.Exists(prevlogFileName))
                    {
                        s += String.Format("Previous build log File not exists or command line missing -lo. \n");
                    }
                    if (!File.Exists(currlogFileName))
                    {
                        s += String.Format("New build log file not exists or command line missing -ln \n");
                    }
                    CommandLineError(s);
                }
            }
            #endregion AllocationGraph
            #region NoReport
            else if (reportKind != ReportKind.NoReport)
            {
                if (logFileName == "")
                    CommandLineError("Need -l logFileName for report");
                else if (!File.Exists(logFileName))
                    CommandLineError("Log file {0} not found", logFileName);
                else
                {
                    switch (reportKind)
                    {
                        case ReportKind.AllocationReport:
                            Reports.AllocationReport(logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.RelocationReport:
                            Reports.RelocationReport(logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.SurvivorReport:
                            Reports.SurvivorReport(logFileName, startMarker, endMarker, timeMarker);
                            break;

                        case ReportKind.SurvivorDifferenceReport:
                            Reports.SurvivorDifferenceReport(logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.HeapDumpReport:
                            Reports.HeapDumpReport(logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.LeakReport:
                            Reports.LeakReport(logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.FinalizerReport:
                            Reports.FinalizerReport(false, logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.CriticalFinalizerReport:
                            Reports.FinalizerReport(true, logFileName, startMarker, endMarker);
                            break;

                        case ReportKind.CommentReport:
                            Reports.CommentReport(logFileName);
                            break;
                    }
                }
            }
            #endregion NoReport
            else
            {
                if (onlyCreateLog)
                {
                    /* treat everything after the exe name to profile as arguments */
                    for (; i < arguments.Length; i++)
                    {
                        commandLine += arguments[i] + ' ';
                    }
                }
                /* basic initialization stuff */
                CreatePipe(@"\\.\pipe\OMV_PIPE", false, ref handshakingPipeHandle, ref handshakingPipe);
                CreatePipe(@"\\.\pipe\OMV_LOGGING_PIPE", false, ref loggingPipeHandle, ref loggingPipe);
                instance = this;

                if (!onlyCreateLog)
                {
                    /* standard UI operation */
                    if (help)
                    {
                        ShowUsage();
                        exitProgram = true;
                        return;
                    }
                    noUI = false;
                    //
                    // Required for Windows Form Designer support
                    //
                    InitializeComponent();

                    // Set V4 Desktop CLR to be the default value
                    targetCLRVersioncomboBox.SelectedIndex = 0;

                    font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); ;

                    if (logFileName != "" && File.Exists(logFileName))
                        LoadLogFile(logFileName);

                    EnableDisableViewMenuItems();
                }
                else
                {
                    /* command-line only */
                    noUI = true;
                    exitProgram = true;

                    try
                    {
                        string fileName = (logFileName == "" ? Path.ChangeExtension(processFileName, ".log") : logFileName);
                        string fullPath = Path.GetFullPath(fileName);
                        logDirectory = Path.GetDirectoryName(fullPath);
                        nameToUse = Path.GetFileName(fileName);

                        if (profilingURL == null)
                        {
                            startApplicationButton_Click(null, null);
                        }
                        else
                        {
                            startURLButton_Click(null, null);
                        }

                        if (profilerConnected)
                        {
                            Environment.ExitCode = 0;
                        }
                        else
                        {
                            Environment.ExitCode = 1;
                        }

                        while (profiledProcess != null && !ProfiledProcessHasExited())
                            Thread.Sleep(500);
                    }
                    catch (Exception e)
                    {
                        throw new Exception(e.Message + '\n' + e.StackTrace);
                        // Console.WriteLine("There was a problem profiling {0}", processFileName);
                    }
                }
            }
        }
        internal void ViewGraph(ReadLogResult logResult, string exeName, Graph.GraphType graphType)
        {
            string fileName = log.fileName;

            if (exeName != null)
            {
                fileName = exeName;
            }
            Graph  graph = null;
            string title = "";

            switch (graphType)
            {
            case Graph.GraphType.CallGraph:
                graph           = logResult.callstackHistogram.BuildCallGraph(new FilterForm());
                graph.graphType = Graph.GraphType.CallGraph;
                title           = "Call Graph for: ";
                break;

            case Graph.GraphType.AssemblyGraph:
                graph           = logResult.callstackHistogram.BuildAssemblyGraph(new FilterForm());
                graph.graphType = Graph.GraphType.AssemblyGraph;
                title           = "Assembly Graph for: ";
                break;

            case Graph.GraphType.AllocationGraph:
                graph           = logResult.allocatedHistogram.BuildAllocationGraph(new FilterForm());
                graph.graphType = Graph.GraphType.AllocationGraph;
                title           = "Allocation Graph for: ";
                break;

            case Graph.GraphType.HeapGraph:
                graph = logResult.objectGraph.BuildTypeGraph(new FilterForm());
                title = "Heap Graph for: ";
                break;

            case Graph.GraphType.FunctionGraph:
                graph           = logResult.functionList.BuildFunctionGraph(new FilterForm());
                graph.graphType = Graph.GraphType.FunctionGraph;
                title           = "Function Graph for: ";
                break;

            case Graph.GraphType.ModuleGraph:
                graph           = logResult.functionList.BuildModuleGraph(new FilterForm());
                graph.graphType = Graph.GraphType.ModuleGraph;
                title           = "Module Graph for: ";
                break;

            case Graph.GraphType.ClassGraph:
                graph           = logResult.functionList.BuildClassGraph(new FilterForm());
                graph.graphType = Graph.GraphType.ClassGraph;
                title           = "Class Graph for: ";
                break;

            default:
                Debug.Assert(false);
                break;
            }
            title += fileName;
            GraphViewForm graphViewForm = new GraphViewForm(graph, title);

            graphViewForm.Visible = true;
        }
示例#7
0
 private void readLogFile(ReadNewLog log, ReadLogResult logResult, string exeName, Graph.GraphType graphType)
 {
     log.ReadFile(logFileStartOffset, logFileEndOffset, logResult);
     //ViewGraph(logResult, exeName, graphType);
 }