public void Run() { Implementation impl; var rd = ""; while (true) { if (!impls.TryTake(out impl)) { break; } while (!resources.TryTake(out rd)) { Thread.Sleep(100); } sem.WaitOne(); var wd = Path.Combine(rd, impl.Name); // create new directory for each entrypoint Directory.CreateDirectory(wd); // create new directory for each entrypoint RemoteExec.CleanDirectory(wd); var pruneFile = Path.Combine(wd, "pruneSlice.bpl"); Program newprogram; // lock because Parsing a program is not thread-safe lock (fslock) { BoogieUtil.PrintProgram(program, pruneFile); // dump original program (so that each entrypoint has its own copy of program) newprogram = BoogieUtil.ReadAndOnlyResolve(pruneFile); // entrypoint's copy of the program } // slice the program by entrypoints Program shallowP = pruneDeepProcs(newprogram, ref edges, impl.Name, approximationDepth, implNames); BoogieUtil.pruneProcs(shallowP, shallowP.TopLevelDeclarations.OfType <Procedure>() .Where(proc => BoogieUtil.checkAttrExists("entrypoint", proc.Attributes)) .Select(proc => proc.Name) .FirstOrDefault()); File.Delete(pruneFile); lock (fslock) { BoogieUtil.PrintProgram(shallowP, pruneFile); // dump sliced program } sem.Release(); if (Driver.createEntryPointBplsOnly) { Console.WriteLine("Skipping AVN run for {0} given /createEntrypointBplsOnly", impl.Name); resources.Add(rd); continue; } if (!remotedirs.Contains(rd)) { Console.WriteLine("Running entrypoint {0} locally {{", impl.Name); if (deadlineReached) { return; } // spawn the job -- local var output = RemoteExec.run(wd, avnPath, string.Format("\"{0}\" {1}", pruneFile, avnArgs)); lock (fslock) { // delete temp files if (!keepFiles) { var files = System.IO.Directory.GetFiles(wd, "*.bpl"); foreach (var f in files) { System.IO.File.Delete(f); } } using (StreamWriter sw = new StreamWriter(Path.Combine(wd, "stdout.txt"))) output.Iter(s => sw.WriteLine("{0}", s)); } Console.WriteLine("Running entrypoint {0} locally }}", impl.Name); } else { // spawn the job -- remote if (psexecPath == null) { throw new FileNotFoundException("Cannot find PSEXEC!"); } // find the name of the machine from the remote folder name var machine = ""; var remoteroot = RemoteExec.GetRemoteFolder(rd, out machine); Console.WriteLine("Running entrypoint {0} on {1} {{", impl.Name, machine); // psexec machine -w remoteroot\impl remoteroot\fastavn\fastavn.exe remoteroot args wd = Path.Combine(remoteroot, impl.Name); var cmd = string.Format("{0} -w {1} {2} {3} {4}", machine, wd, Path.Combine(remoteroot, "fastavn", "AngelicVerifierNull.exe"), "pruneSlice.bpl", avnArgs); //Console.WriteLine("PSEXEC Running: {0}", cmd); if (deadlineReached) { return; } var output = RemoteExec.run(Directory.GetCurrentDirectory(), psexecPath, cmd); lock (fslock) { // delete temp files var td = Path.Combine(rd, impl.Name); if (debug) { Console.WriteLine("Getting files in directory: {0}", td); } var files = System.IO.Directory.GetFiles(td, "*.bpl"); foreach (var f in files) { if (debug) { Console.WriteLine("Deleting {0}", f); } System.IO.File.Delete(f); } // copy the results back var ld = Path.Combine(Directory.GetCurrentDirectory(), impl.Name); Directory.CreateDirectory(ld); RemoteExec.CleanDirectory(ld); RemoteExec.CopyFolder(rd, Directory.GetCurrentDirectory(), impl.Name, true); using (StreamWriter sw = new StreamWriter(Path.Combine(ld, "stdout.txt"))) output.Iter(s => sw.WriteLine("{0}", s)); } Console.WriteLine("Running entrypoint {0} on {1} }}", impl.Name, machine); } lock (fslock) { // collect and merge bugs var bugs = collectBugs(Path.Combine(Directory.GetCurrentDirectory(), impl.Name, bugReportFileName)); bugs.Iter(b => { if (!mergedBugs.ContainsKey(b)) { mergedBugs[b] = 0; } mergedBugs[b] += 1; }); Utils.Print(string.Format("Bugs found so far: {0}", mergedBugs.Count)); resources.Add(rd); } } }
/// <summary> /// Run AVN binary on sliced programs /// </summary> /// <param name="prog">Original program</param> /// <param name="approximationDepth">Depth k beyond which angelic approximation is applied</param> private static void sliceAndRunAVN(Program prog, int approximationDepth, HashSet <string> epNames) { edges = buildCallGraph(prog); // Create a list of resources var worklist = new ConcurrentBag <string>(); for (int i = 0; i < numThreads; i++) { worklist.Add(Directory.GetCurrentDirectory()); } if (config != null) { foreach (var r in config.RemoteRoots) { remotedirs.Add(r.dir); for (int i = 0; i < r.Threads; i++) { worklist.Add(r.dir); } } } worklist = Shuffle(worklist); // Install FASTAVN foreach (var rd in remotedirs) { Console.WriteLine("Installing on {0}", rd); Directory.CreateDirectory(Path.Combine(rd, "fastavn")); RemoteExec.CopyFolder(Path.GetDirectoryName(avnPath), Path.Combine(rd, "fastavn"), true); } // max threads var threadsToSpawn = worklist.Count; // semaphore for limiting at most numThreads threads running at one time on local machine var sem = new Semaphore(numThreads, numThreads); // entrypoints var entrypoints = new ConcurrentBag <Implementation>(prog.TopLevelDeclarations.OfType <Implementation>() .Where(impl => epNames.Contains(impl.Name))); // deadline if (deadline > 0) { deadline = deadline - (int)((DateTime.Now - startingTime).TotalSeconds + 0.5); if (deadline < 0) { deadline = 1; } } if (deadline > 100) { var timeouttask = new System.Threading.Tasks.Task(() => { System.Threading.Thread.Sleep((deadline - 100) * 1000); Console.WriteLine("FastAvn deadline reached; consolidating results"); deadlineReached = true; KillSpawnedProcesses(); // Sleep for 2 seconds System.Threading.Thread.Sleep(2 * 1000); // collate bugs lock (fslock) { if (printingOutput) { return; } printingOutput = true; printBugs(ref mergedBugs, epNames.Count); mergeBugs(epNames); } // Kill self Process.GetCurrentProcess().Kill(); }); timeouttask.Start(); } else if (deadline != 0) { Console.WriteLine("Ignoring small deadline of {0} seconds", deadline); } var threads = new List <Thread>(); for (int i = 0; i < threadsToSpawn; i++) { var w = new Worker(prog, entrypoints, worklist, sem); threads.Add(new Thread(new ThreadStart(w.Run))); } threads.Iter(t => t.Start()); threads.Iter(t => t.Join()); if (Driver.createEntryPointBplsOnly) { Console.WriteLine("Early exit due to /createEntryPointBplsOnly"); return; } lock (fslock) { if (printingOutput) { return; } printingOutput = true; printBugs(ref mergedBugs, epNames.Count); mergeBugs(epNames); } }