Example #1
0
        // Check if the specified pid is a WindowsStoreApp.  If so, initialize
        // a new windowsStoreAppProfileeInfo based on it.
        // If there's an error doing so, return false.  If we successfully
        // get the WindowsStoreApp info, or if pid isn't a WindowsStoreApp process at all,
        // return true.
        private bool InitWindowsStoreAppProfileeInfoIfNecessary(int pid)
        {
            WindowsStoreAppHelperWrapper.Init();
            if (WindowsStoreAppHelperWrapper.IsWindowsStoreAppSupported())
            {
                string acSid;
                string acFolderPath;
                string windowsStoreAppPackageFullName = null;
                WindowsStoreAppHelperWrapper.GetWindowsStoreAppInfoFromProcessId(pid, out acSid, out acFolderPath, out windowsStoreAppPackageFullName);
                if (acSid != null)
                {
                    // Ensure WindowsStoreApp packages will have access to CLRProfiler binaries
                    if (!WindowsStoreAppHelperWrapper.IsWindowsStoreAppAccessEnabledForProfiler(Path.GetDirectoryName(Application.ExecutablePath)))
                        return false;

                    windowsStoreAppProfileeInfo = new WindowsStoreAppProfileeInfo(windowsStoreAppPackageFullName, acSid);
                    InitWindowsStoreAppLogDirectory(acFolderPath);

                    // Before we send the attach signal to the profilee, we
                    // want to enable "debugging" mode, to ensure it's awake
                    // and won't get suspended
                    WindowsStoreAppHelperWrapper.EnableDebuggingForPackage(windowsStoreAppPackageFullName);
                }
            }
            else
            {
                startWindowsStoreAppButton.Enabled = false;
            }

            return true;
        }
Example #2
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);
                    }
                }
            }
        }
Example #3
0
        private void startWindowsStoreAppButton_Click(object sender, EventArgs e)
        {
            if (!CheckProcessTerminate() || !CheckFileSave())
                return;

            // Win 8 check
            WindowsStoreAppHelperWrapper.Init();
            if (!WindowsStoreAppHelperWrapper.IsWindowsStoreAppSupported())
            {
                // Error message was already displayed by WindowsStoreAppHelperWrapper
                startWindowsStoreAppButton.Enabled = false;
                return;
            }

            if (WindowsStoreAppHelperWrapper.IsRunningElevated())
            {
                MessageBox.Show("CLRProfiler cannot launch a Windows Store app when running elevated.  Please rerun CLRProfiler non-elevated and try again.");
                return;
            }

            // Ensure WindowsStoreApp packages will have access to CLRProfiler binaries
            if (!WindowsStoreAppHelperWrapper.IsWindowsStoreAppAccessEnabledForProfiler(Path.GetDirectoryName(Application.ExecutablePath)))
                return;

            // User picks the package
            
            WindowsStoreAppChooserForm windowsStoreAppAppChooserForm = new WindowsStoreAppChooserForm();
            DialogResult result = windowsStoreAppAppChooserForm.ShowDialog();
            if (result == DialogResult.Cancel)
                return;

            string packageFullName = windowsStoreAppAppChooserForm.SelectedPackageFullName;
            string appUserModelId = windowsStoreAppAppChooserForm.SelectedAppUserModelId;
            string acSidString = windowsStoreAppAppChooserForm.SelectedAcSidString;

            windowsStoreAppProfileeInfo = new WindowsStoreAppProfileeInfo(packageFullName, acSidString);
            InitWindowsStoreAppLogDirectory(windowsStoreAppAppChooserForm.SelectedPackageTempDir);

            // Launch the WindowsStoreApp with the right environment variables
            processFileName = windowsStoreAppAppChooserForm.SelectedProcessFileName;
            uint pid;
            WindowsStoreAppHelperWrapper.SpawnWindowsStoreAppProcess(
                packageFullName,
                appUserModelId,
                "",         // App args
                CreateProfilerEnvironment(logDirectory),
                out pid);

            // There was an error spawning the WindowsStoreApp process; an error message should
            // already have been displayed.
            if ((int)pid == -1)
                return;

            profiledProcess = Process.GetProcessById((int) pid);

            if (WaitForWindowsStoreAppProcessToConnect(pid, "Waiting for Windows Store application to start common language runtime") <= 0)
                ClearProfiledProcessInfo();
        }
Example #4
0
        private void ClearProfiledProcessInfo()
        {
            profiledProcess = null;
            profilerConnected = false;
            if (WindowsStoreAppHelperWrapper.IsWindowsStoreAppSupported() && IsProfilingWindowsStoreApp())
            {
                WindowsStoreAppHelperWrapper.DisableDebuggingForPackage(windowsStoreAppProfileeInfo.packageFullName);
            }

            windowsStoreAppProfileeInfo = null;
        }