Пример #1
0
        public static int Drive(string assemblyName, bool verbose, Dictionary <string, string> environment)
        {
            string assemblyPath             = Path.GetFullPath(assemblyName);
            string assemblyPathAsFile       = Util.MapPathToFileName(assemblyPath);
            string PMI_FILE_MARKER          = $"NextMethodToPrep-{assemblyPathAsFile}.marker";
            string PREVIOUS_PMI_FILE_MARKER = $"PreviousNextMethodToPrep-{assemblyPathAsFile}.marker";

            if (File.Exists(PMI_FILE_MARKER))
            {
                File.Delete(PMI_FILE_MARKER);
            }
            if (File.Exists(PREVIOUS_PMI_FILE_MARKER))
            {
                File.Delete(PREVIOUS_PMI_FILE_MARKER);
            }

            PrepAllInfo pi = new PrepAllInfo();

            pi.assemblyName = assemblyName;
            pi.methodToPrep = 0;
            pi.environment  = environment;

            bool isFileCompleted   = false;
            int  prepallRetryCount = 0;

            List <string> errors = new List <string>();

            while (!isFileCompleted && prepallRetryCount <= PREPALL_MAX_RETRY_COUNT)
            {
                prepallRetryCount++;
                PrepAllResult pr = Compute(pi);
                if (pr.success)
                {
                    isFileCompleted = true;
                }
                else
                {
                    if (pr.assert)
                    {
                        errors.Add(String.Format("{0}###{1}", pr.errorMessage, pr.errorDetail));
                        try
                        {
                            int nextMethodToPrep = Int32.Parse(File.ReadAllLines(PMI_FILE_MARKER)[0]);
                            Console.WriteLine("Current Method: " + pi.methodToPrep + " nextMethodToPrep: " + nextMethodToPrep);
                            if (pi.methodToPrep == nextMethodToPrep)
                            {
                                // We failed, in the same spot as last time. So there's no point continuing.
                                isFileCompleted = true;
                            }
                            else
                            {
                                pi.methodToPrep = nextMethodToPrep + 1;
                                using (var writer = new StreamWriter(File.Create(PREVIOUS_PMI_FILE_MARKER)))
                                {
                                    writer.Write("{0}", pi.methodToPrep + 1);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            if (errors.Count > 0)
                            {
                                File.WriteAllLines(String.Format("{0}.err",
                                                                 Path.GetFileNameWithoutExtension(pi.assemblyName)), errors);
                            }
                            else
                            {
                                Console.WriteLine("ERROR: No errors to write");
                            }

                            // Try the previous one again
                            if (File.Exists(PREVIOUS_PMI_FILE_MARKER))
                            {
                                pi.methodToPrep = Int32.Parse(File.ReadAllLines(PREVIOUS_PMI_FILE_MARKER)[0]);
                            }
                            else
                            {
                                // There is some problem with this file. Abondon this file.
                                isFileCompleted = true;
                                File.AppendAllText(String.Format("{0}.err",
                                                                 Path.GetFileNameWithoutExtension(pi.assemblyName)),
                                                   String.Format("PROBLEM with file - {0} cant be found", PREVIOUS_PMI_FILE_MARKER));
                            }

                            if (!File.Exists(PMI_FILE_MARKER))
                            {
                                // There is some problem with this file. Abondon this file.
                                isFileCompleted = true;
                                File.AppendAllText(String.Format("{0}.err",
                                                                 Path.GetFileNameWithoutExtension(pi.assemblyName)),
                                                   String.Format("PROBLEM with file - {0} cant be found", PMI_FILE_MARKER));
                            }
                        }
                    }
                    else
                    {
                        errors.Add(pr.errorMessage);
                        isFileCompleted = true;
                    }
                }
            }

            // Clean up our temporary files
            try
            {
                if (File.Exists(PMI_FILE_MARKER))
                {
                    File.Delete(PMI_FILE_MARKER);
                }
                if (File.Exists(PREVIOUS_PMI_FILE_MARKER))
                {
                    File.Delete(PREVIOUS_PMI_FILE_MARKER);
                }
            }
            catch (Exception)
            {
                // Ignore failures
            }

            if (errors.Count > 0)
            {
                File.WriteAllLines(String.Format("{0}.err", Path.GetFileNameWithoutExtension(pi.assemblyName)), errors);
                return(200); // error return
            }
            else
            {
                return(0); // success return
            }
        }
Пример #2
0
        private static PrepAllResult Compute(PrepAllInfo pi)
        {
            PrepAllResult temp = new PrepAllResult();

            temp.success = false;
            temp.assert  = false;

            string szOutput = null;
            string szError  = null;

            try
            {
                Process p = new Process();
                p.StartInfo.UseShellExecute        = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError  = true;
                p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
                                                                    { szError += e.Data; });

                foreach (var pair in pi.environment)
                {
                    p.StartInfo.EnvironmentVariables[pair.Key] = pair.Value;
                }

                // Fetch our command line. Split off the arguments.
#if NETCOREAPP
                // For .Net Core the PMI assembly is an argument to dotnet.
                string newCommandLine = Environment.CommandLine.Replace("DRIVEALL", "PREPALL");
#else
                // For .Net Framework the OS knows how to bootstrap .Net when
                // passed the PMI assembly as an executable.
                string newCommandLine = "PREPALL \"" + pi.assemblyName + "\"";
#endif
                newCommandLine += " " + pi.methodToPrep;

                Process thisProcess = Process.GetCurrentProcess();
                string  driverName  = thisProcess.MainModule.FileName;

                p.StartInfo.FileName  = driverName;
                p.StartInfo.Arguments = newCommandLine;

                Console.WriteLine($"DRIVEALL: Invoking {driverName} {newCommandLine}");

                p.Start();
                p.BeginErrorReadLine();
                szOutput = p.StandardOutput.ReadToEnd();

                if (!p.WaitForExit(PREPALL_TIMEOUT))
                {
                    try
                    {
                        KillProcessAndChildren(p.Id);
                    }
                    catch (InvalidOperationException) { }
                    catch (Win32Exception) { }
                }

                szOutput = szOutput + szError;
                Console.WriteLine(szOutput);
                int idx = szOutput.IndexOf("Completed assembly ");
                if (idx == -1)
                {
                    //File.WriteAllText(pi.assemblyName + ".prepall", szOutput);
                    idx = szOutput.IndexOf("]): Assertion failed '");
                    if (idx != -1)
                    {
                        temp.assert = true;
                        //Assert failure(PID 440 [0x000001b8], Thread: 3220 [0xc94]): Assertion failed 'genActualType(tree->gtType) == TYP_INT || genActualType(tree->gtType) == TYP_I_IMPL || genActualType(tree->gtType) == TYP_REF || tree->gtType == TYP_BYREF' in 'ELP.Program:Main(ref):int'
                        //File: c:\dd\arm_1\src\ndp\clr\src\jit\il\codegen.cpp, Line: 945 Image:
                        int    idx2   = szOutput.IndexOf("Image:", idx);
                        string szTemp = szOutput.Substring(idx, idx2 - idx);
                        //]): Assertion failed 'genActualType(tree->gtType) == TYP_INT || genActualType(tree->gtType) == TYP_I_IMPL || genActualType(tree->gtType) == TYP_REF || tree->gtType == TYP_BYREF' in 'ELP.Program:Main(ref):int'
                        //File: c:\dd\arm_1\src\ndp\clr\src\jit\il\codegen.cpp, Line: 945 Image:
                        string[] szTemp2 = szTemp.Split('\'');
                        temp.errorMessage = szTemp2[1];
                        temp.errorDetail  = szTemp2[3];
                        temp.assemblyName = pi.assemblyName;
                    }
                    else
                    {
                        idx = szOutput.IndexOf("Assert failure(PID ");
                        if (idx != -1)
                        {
                            temp.assert = true;

                            //Assert failure(PID 12020 [0x00002ef4], Thread: 13276 [0x33dc]): (entry == NULL) || (entry == GetSlot(numGenericArgs,i)) || IsCompilationProcess()
                            //CLR! Dictionary::PrepopulateDictionary + 0x135 (0x603435b8)
                            //CLR! MethodCallGraphPreparer::PrepareMethods + 0x24B (0x602e7e45)
                            //CLR! MethodCallGraphPreparer::Run + 0x45E (0x602e7308)
                            //CLR! PrepareMethodDesc + 0x11B (0x602e9559)
                            //CLR! ReflectionInvocation::PrepareMethod + 0x596 (0x60494ac0)
                            //MSCORLIB.NI! <no symbol> + 0x0 (0x5e4aff9d)
                            //<no module>! <no symbol> + 0x0 (0x005821b7)
                            //CLR! CallDescrWorkerInternal + 0x34 (0x5fddcb2d)
                            //CLR! CallDescrWorker + 0xD5 (0x600da980)
                            //CLR! CallDescrWorkerWithHandler + 0x1B9 (0x600daba1)
                            //    File: c:\clr2\src\ndp\clr\src\vm\genericdict.cpp, Line: 933 Image:
                            //c:\pmi\pmi.exe

                            idx = szOutput.IndexOf("]): ", idx);
                            int    idx2   = szOutput.IndexOf("\r\n", idx);
                            string szTemp = szOutput.Substring(idx + 4, idx2 - idx - 4);
                            //(entry == NULL) || (entry == GetSlot(numGenericArgs,i)) || IsCompilationProcess()
                            temp.errorMessage = szTemp;
                            //temp.errorDetail = szTemp2[3];
                            temp.assemblyName = pi.assemblyName;
                        }
                        else
                        {
                            Console.WriteLine("Failed PREPALL on {0}", pi.assemblyName);
                            temp.errorMessage = "General error, no assert seen.";
                        }
                    }
                }
                else
                {
                    temp.success = true;
                }
            }
            catch (Exception e)
            {
                temp.errorMessage = e.ToString();
            }
            return(temp);
        }