Example #1
0
    // Return values:
    // 0 - success
    // >= 100 - failure
    public static int Main(string[] args)
    {
        if (args.Length < 2)
        {
            return(Usage());
        }

        string command      = args[0].ToUpper();
        string assemblyName = args[1];
        int    methodToPrep = -1; // For PREPONE, PREPALL. For PREPALL, this is the first method to prep.

        Visitor v = null;

        int    dashIndex   = command.IndexOf('-');
        string rootCommand = dashIndex < 0 ? command : command.Substring(0, dashIndex);

        switch (rootCommand)
        {
        case "DRIVEALL":
        case "COUNT":
            if (args.Length < 2)
            {
                Console.WriteLine("ERROR: too few arguments");
                return(Usage());
            }
            else if (args.Length > 2)
            {
                Console.WriteLine("ERROR: too many arguments");
                return(Usage());
            }

            if (command == "DRIVEALL")
            {
                return(PMIDriver.PMIDriver.Drive(assemblyName));
            }

            v = new Counter();
            break;

        case "PREPALL":
        case "PREPONE":
            if (args.Length < 3)
            {
                methodToPrep = 0;
            }
            else if (args.Length > 3)
            {
                Console.WriteLine("ERROR: too many arguments");
                return(Usage());
            }
            else
            {
                try
                {
                    methodToPrep = Convert.ToInt32(args[2]);
                }
                catch (System.FormatException)
                {
                    Console.WriteLine("ERROR: illegal method number");
                    return(Usage());
                }
            }

            bool all     = command.IndexOf("ALL") > 0;
            bool verbose = !(command.IndexOf("QUIET") > 0);
            bool time    = verbose || command.IndexOf("TIME") > 0;

            if (all)
            {
                v = new PrepareAll(methodToPrep, verbose, time);
            }
            else
            {
                v = new PrepareOne(methodToPrep, verbose, time);
            }
            break;

        default:
            Console.WriteLine("ERROR: Unknown command {0}", command);
            return(Usage());
        }

        // We want to handle specifying a "load path" where assemblies can be found.
        // The environment variable PMIPATH is a semicolon-separated list of paths. If the
        // Assembly can't be found by the usual mechanisms, our Assembly ResolveEventHandler
        // will be called, and we'll probe on the PMIPATH list.
        AppDomain currentDomain = AppDomain.CurrentDomain;

        currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandler);

        Worker w      = new Worker(v);
        int    result = 0;
        string msg    = "a file";

#if NETCOREAPP2_1
        msg += " or a directory";
        if (Directory.Exists(assemblyName))
        {
            EnumerationOptions options = new EnumerationOptions();
            options.RecurseSubdirectories = true;
            IEnumerable <string> exeFiles = Directory.EnumerateFiles(assemblyName, "*.exe", options);
            IEnumerable <string> dllFiles = Directory.EnumerateFiles(assemblyName, "*.dll", options);
            IEnumerable <string> allFiles = exeFiles.Concat(dllFiles);
            result = w.Work(allFiles);
        }
        else
#endif

        if (File.Exists(assemblyName))
        {
            result = w.Work(assemblyName);
        }
        else
        {
            Console.WriteLine($"ERROR: {assemblyName} is not {msg}");
            result = 101;
        }

        return(result);
    }
Example #2
0
    // Return values:
    // 0 - success
    // >= 100 - failure
    public static int Main(string[] args)
    {
        if (args.Length < 2)
        {
            return(Usage());
        }

        // TlsOverPerCoreLockedStacksArrayPool.Return registers Gen2GcCallbackFunc on Gen2GcCallback.
        // Gen2GcCallbackFunc is then called from Gen2GcCallback finalizer after a gc.
        // For output determinism we force the registration of Gen2GcCallbackFunc and then force a gc
        // so that Gen2GcCallbackFunc is jitted.
        EnsureGen2GcCallbackFuncIsJitted();

        string command      = args[0].ToUpper();
        string assemblyName = args[1];
        int    methodToPrep = -1; // For PREPONE, PREPALL. For PREPALL, this is the first method to prep.

        Visitor v = null;

        int    dashIndex   = command.IndexOf('-');
        string rootCommand = dashIndex < 0 ? command : command.Substring(0, dashIndex);
        bool   verbose     = !(command.IndexOf("QUIET") > 0);

        switch (rootCommand)
        {
        case "DRIVEALL":
        case "COUNT":
            if (args.Length < 2)
            {
                Console.WriteLine("ERROR: too few arguments");
                return(Usage());
            }
            else if (args.Length > 2)
            {
                Console.WriteLine("ERROR: too many arguments");
                return(Usage());
            }

            if (rootCommand == "DRIVEALL")
            {
                string pmiEnv = Environment.GetEnvironmentVariable("PMIENV");
                Dictionary <string, string> environment = new Dictionary <string, string>();
                if ((pmiEnv != null) && (pmiEnv.Length != 0))
                {
                    Regex           rx      = new Regex(@"^(?:(?<name>[\w_]+)=(?<value>[^;]+);)*(?<lastname>[\w_]+)=(?<lastvalue>[^$]+)$");
                    MatchCollection matches = rx.Matches(pmiEnv);
                    if (matches.Count != 1)
                    {
                        Console.WriteLine("ERROR: PMIENV format is incorrect");
                        return(Usage());
                    }
                    Match           match  = matches[0];
                    GroupCollection groups = match.Groups;
                    for (int i = 0; i < groups["name"].Captures.Count; ++i)
                    {
                        environment[groups["name"].Captures[i].Value] = groups["value"].Captures[i].Value;
                    }
                    environment[groups["lastname"].Captures[0].Value] = groups["lastvalue"].Captures[0].Value;
                }

                return(PMIDriver.PMIDriver.Drive(assemblyName, verbose, environment));
            }

            v = new Counter();
            break;

        case "PREPALL":
        case "PREPONE":
            if (args.Length < 3)
            {
                methodToPrep = 0;
            }
            else if (args.Length > 3)
            {
                Console.WriteLine("ERROR: too many arguments");
                return(Usage());
            }
            else
            {
                try
                {
                    methodToPrep = Convert.ToInt32(args[2]);
                }
                catch (System.FormatException)
                {
                    Console.WriteLine("ERROR: illegal method number");
                    return(Usage());
                }
            }

            bool all  = command.IndexOf("ALL") > 0;
            bool time = verbose || command.IndexOf("TIME") > 0;

            if (all)
            {
                v = new PrepareAll(methodToPrep, verbose, time);
            }
            else
            {
                v = new PrepareOne(methodToPrep, verbose, time);
            }
            break;

        default:
            Console.WriteLine("ERROR: Unknown command {0}", command);
            return(Usage());
        }

        bool runCctors            = command.IndexOf("CCTORS") > 0;
        bool logTailCallDecisions = command.IndexOf("TAILCALLS") > 0;
        bool logInliningDecisions = command.IndexOf("INLINES") > 0;

        if (logTailCallDecisions)
        {
            JITDecisionEventListener.s_enabledEvents.Add("MethodJitTailCallSucceeded");
            JITDecisionEventListener.s_enabledEvents.Add("MethodJitTailCallFailed");
        }
        if (logInliningDecisions)
        {
            JITDecisionEventListener.s_enabledEvents.Add("MethodJitInliningSucceeded");
            JITDecisionEventListener.s_enabledEvents.Add("MethodJitInliningFailed");
        }

        using var eventListener =
                  logTailCallDecisions || logInliningDecisions ? new JITDecisionEventListener() : null;

        Worker w      = new Worker(v, runCctors);
        int    result = 0;
        string msg    = "a file";

#if NETCOREAPP
        msg += " or a directory";
        if (Directory.Exists(assemblyName))
        {
            EnumerationOptions options = new EnumerationOptions();
            options.RecurseSubdirectories = true;
            IEnumerable <string> exeFiles = Directory.EnumerateFiles(assemblyName, "*.exe", options);
            IEnumerable <string> dllFiles = Directory.EnumerateFiles(assemblyName, "*.dll", options);
            IEnumerable <string> allFiles = exeFiles.Concat(dllFiles);
            result = w.Work(allFiles);
        }
        else
#endif

        if (File.Exists(assemblyName))
        {
            result = w.Work(assemblyName);
        }
        else
        {
            Console.WriteLine($"ERROR: {assemblyName} is not {msg}");
            result = 101;
        }

        return(result);
    }