Пример #1
0
        private int MainInternal(string name, string[] args, TextWriterAsync textWriter)
        {
            Contract.Requires(name != null);
            Contract.Requires(args != null);
            Contract.Requires(textWriter != null);
            try
            {
                CloudotLogging.LogAnalysiRequest(name, args);
#if INTERNALCALL
                return(CallClousotInternally(name, args, textWriter));
#else
                return(CallClousotViaProcess(name, args, textWriter));
#endif
            }
            catch (ExitRequestedException e)
            {
                return(e.ExitCode);
            }
            catch (Exception e)
            {
                CloudotLogging.WriteLine("Got an exception. Reporting it to the client and aborting the session.");
                // We need to catch all exception, otherwise the service is turned into an faulted state and remains unusable
                textWriter.WriteLine("Cloudot: caught exception: {0}".PrefixWithCurrentTime(), e);
                if (e.InnerException != null)
                {
                    textWriter.WriteLine("Inner exception: {0}", e.InnerException);
                }
                return(-4444);
            }
            finally
            {
                CloudotLogging.WriteLine("Analysis of request #{0} done in {1}", this.myId, DateTime.Now - this.start);
                textWriter.Close(); // make sure all pending output is flushed
            }
        }
Пример #2
0
        [Pure] // Even if we change the file system...
        public static bool TryRestoreAnalysisPackage(string packageFileName, string outputDir, out string[] clousotNormalizedParameters)
        {
            Contract.Requires(packageFileName != null);
            Contract.Requires(outputDir != null);
            Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out clousotNormalizedParameters) != null);

            clousotNormalizedParameters = null;
            try
            {
                // Step 0: make sure the directory exists
                DirectoryInfo outputDirInfo;
                if (Directory.Exists(outputDir))
                {
                    outputDirInfo = new DirectoryInfo(outputDir);
                }
                else
                {
                    outputDirInfo = Directory.CreateDirectory(outputDir);
                }

                if (TryRestorePackage(packageFileName, outputDir))
                {
                    return(true);
                }

                return(false);
            }
            catch (Exception e)
            {
                CloudotLogging.WriteLine("Something went wrong in restoring the package (exception of type {0}). Aborting.", e.GetType());
                return(false);
            }
        }
Пример #3
0
        private static string[] ForgeClousotCommandLineFromOutputFile(string outputDir)
        {
            try
            {
                var lines            = File.ReadAllLines(Path.Combine(outputDir, CloudotInstructionsFileName));
                var result           = new List <string>();
                var optionsWithPaths = GeneralOptions.GetClousotOptionsWithPaths().ToArray();
                var optionsBounds    = FindOptions(lines);
                for (var i = optionsBounds.Item1; i < optionsBounds.Item2; i++)
                {
                    var line = lines[i];
                    if (line.Length > 0)
                    {
                        var subLine = line.Substring(1);
                        if (optionsWithPaths.Any(optionName => subLine.StartsWith(optionName)))
                        {
                            line = ReplaceVolumesWithLocalRootPath(outputDir, line);
                        }
                        else if (IsPath(line))
                        {
                            line = ReplaceVolumesWithLocalRootPath(outputDir, line);
                        }
                    }
                    result.Add(line);
                }

                return(result.ToArray());
            }
            catch (Exception)
            {
                CloudotLogging.WriteLine("Something went wrong while getting the cmd line from dir {0}", outputDir);
                return(null);
            }
        }
Пример #4
0
        private void CreateProcessesAndPopulateTheQueue(int initialCount = INITIALPOOLSIZE)
        {
            Contract.Requires(initialCount >= 0);

            lock (this.availableWorkers)
            {
                CloudotLogging.WriteLine("Creating {0} workers", initialCount);
                for (var i = 0; i < initialCount; i++)
                {
                    var processInfo = SetupProcessInfoToWait();

                    try
                    {
                        var exe = Process.Start(processInfo);
                        if (exe != null)
                        {
                            this.availableWorkers.Enqueue(exe);
                        }
                        else
                        {
                            CloudotLogging.WriteLine("Failed to create the Clousot process");
                        }
                    }
                    catch
                    {
                        CloudotLogging.WriteLine("Error in starting the Clousot/cccheck process for the pool");
                    }
                }
            }
        }
Пример #5
0
        private void Dispose(bool Disposing)
        {
            // We want to make sure there are no zombie processes left
            CloudotLogging.WriteLine("Killing all the workers");
            foreach (var exe in this.availableWorkers)
            {
                try
                {
                    if (!exe.HasExited)
                    {
                        exe.Kill();
                    }
                }
                catch (Exception e)
                {
                    CloudotLogging.WriteLine("[Debug] Exception raised while trying to kill the idle process {0} -- We just continue as it means that the OS has already removed the process", exe.Id);
                    CloudotLogging.WriteLine("[Debug] Exception {0}", e);
                }
            }

            foreach (var exe in this.scheduledWorkers)
            {
                try
                {
                    if (!exe.HasExited)
                    {
                        exe.Kill();
                    }
                }
                catch (Exception e)
                {
                    CloudotLogging.WriteLine("Exception {0} raised while trying to kill an active process -- We just continue as it means that the process was already terminated", e.GetType());
                }
            }
        }
Пример #6
0
        public int AnalyzeUsingAnalysisPackage(string name, string packageLocation, string encodingWebName)
        {
            // Step 0: initialize the server
            var textWriter = InitializeServiceInstance(new string[] { packageLocation }, encodingWebName);

            // Step 1: Compute the location in the Semantic index
            var semanticIndexLocation = ComputeSemanticIndexLocation(name);

            // Step 1: restore the package
            string[] clousotOptions;
            if (FileTransfer.TryRestoreAnalysisPackage(packageLocation, semanticIndexLocation, out clousotOptions))
            {
                CloudotLogging.WriteLine("Package restored, command line on the server {0}", String.Join(" ", clousotOptions));
                return(MainInternal(name, clousotOptions, textWriter));
            }

            return(-1);
        }
Пример #7
0
        private static bool TryRestorePackage(string fileName, string outputDir)
        {
            var start = DateTime.Now;

            try
            {
                CloudotLogging.WriteLine("Restoring the analysis package {0} in {1}", fileName, outputDir);
                using (var zipArchive = ZipFile.OpenRead(fileName))
                {
                    foreach (var entry in zipArchive.Entries)
                    {
                        var destinationFileName = MakeOutputFileName(outputDir, entry.FullName);

                        // If the file was already unzipped, skip it
                        if (File.Exists(destinationFileName))
                        {
                            continue; // Skip the file
                        }

                        // Make sure the destination directory exists
                        var dir = Path.GetDirectoryName(destinationFileName);
                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        entry.ExtractToFile(destinationFileName);
                    }
                }
            }
            catch (Exception e)
            {
                CloudotLogging.WriteLine("Something went wrong in restoring the file {0} (got exception of type {1}). Aborting.", fileName, e.GetType());
                CloudotLogging.WriteLine("Exception: {0}", e);
                return(false);
            }

            CloudotLogging.WriteLine("Done Restoring the analysis package ({0} elapsed)", DateTime.Now - start);

            return(true);
        }
Пример #8
0
        // This Clousot as Service host started from the command line
        // Usage: run it, and wait for readline to kill everything
        // We need a service per box
        public static void Main()
        {
            CloudotLogging.WriteLine("Starting Cloudot service...");
            CloudotLogging.WriteLine();

            try
            {
                using (var host = new ClousotServiceHost())
                {
                    host.AddLogger(Console.Out.AsLineWriter()); // TODO: Replace the Console.Out with the equivalent in CloudotLogging

                    host.Open();

                    CloudotLogging.WriteLine(string.Format("The service is ready and listening at {0}", String.Join(", ", host.BaseAddresses)));
                    CloudotLogging.WriteLine("Press <ENTER> to terminate service.");
                    Console.ReadLine();

                    host.Close();
                }
            }
            catch (TimeoutException timeProblem)
            {
                CloudotLogging.WriteLine(timeProblem.Message);
                if (timeProblem.InnerException != null)
                {
                    CloudotLogging.WriteLine(timeProblem.InnerException.Message);
                }
                Console.ReadLine();
            }
            catch (CommunicationException commProblem)
            {
                CloudotLogging.WriteLine(commProblem.Message);
                if (commProblem.InnerException != null)
                {
                    CloudotLogging.WriteLine(commProblem.InnerException.Message);
                }
                Console.ReadLine();
            }
        }
Пример #9
0
        /// <summary>
        /// Common initialization for the service.
        /// Essentially writes down some logging string and getting the callback on which the service will respond
        /// </summary>
        /// <returns>The text writer object the service will write on</returns>
        private TextWriterAsync InitializeServiceInstance(string[] args, string encodingWebName)
        {
            Contract.Requires(args != null);

            // Update the request, and save some statistics
            this.myId  = RequestId++;
            this.start = DateTime.Now;

            if (this.OnMain != null)
            {
                this.OnMain(args);
            }

            // here is the magic: the callback object is recovered in the line below
            var callbackLineWriter = OperationContext.Current.GetCallbackChannel <IVerySimpleLineWriter>();

            // And now we create the output factory for Clousot
            var textWriter = new TextWriterAsync(callbackLineWriter.AsTextWriter(encodingWebName));

            CloudotLogging.WriteLine("Starting processing request #" + myId);

            return(textWriter);
        }
Пример #10
0
        private void SendWorkToProcess(Process exeProcess, string[] args)
        {
            Contract.Requires(exeProcess != null);
            Contract.Requires(args != null);

            CloudotLogging.WriteLine("Dispatching the analysis to worker process {0}", exeProcess.Id);

            var pipeName = CommonNames.GetPipeNameForCloudotWorker(exeProcess.Id);

            var namedPipeClient = new NamedPipeClientStream(pipeName);

            try
            {
                // Try to connect to the process via the pipe
                namedPipeClient.Connect(200);

                // Send the arguments -- our protocol is that once the clousot process received the arguments, it will proceed with the analysis, as usual
                new BinaryFormatter().Serialize(namedPipeClient, args);
            }
            catch (Exception e)
            {
                CloudotLogging.WriteLine("Something went wrong while sending the arguments to process {0}{1}{2}", exeProcess.Id, Environment.NewLine, e.Message);
            }
        }
Пример #11
0
        protected override void OnClosing()
        {
            CloudotLogging.WriteLine("Closing the service");

            base.OnClosing();
        }
Пример #12
0
        protected override void OnAbort()
        {
            CloudotLogging.WriteLine("Aborting the service");

            base.OnAbort();
        }
Пример #13
0
        protected override void OnClosed()
        {
            CloudotLogging.WriteLine("The service is now closed");

            base.OnClosed();
        }
Пример #14
0
 public ClousotService()
 {
     CloudotLogging.WriteLine("[Debug] Inside Clousot Service constructor");
 }
Пример #15
0
        private int CallClousotViaProcess(string name, string[] args, TextWriter textwriter)
        {
            Contract.Requires(name != null);
            Contract.Requires(args != null);
            Contract.Requires(textwriter != null);

            try
            {
                string outputFileName;
                using (var outputFileOnServer = CloudotLogging.GetAFreshOutputFileName(name, out outputFileName))
                {
                    CloudotLogging.WriteLine("Saving the output at {0}", outputFileName);
                    // Start the process with the info we specified
                    using (var exe = workersPool.GetAProcessFromTheQueue())
                    {
                        SendWorkToProcess(exe, args);

                        // Reads the standard error and pushes it to the
                        Task.Factory.StartNew(
                            () =>
                        {
                            while (!exe.HasExited)
                            {
                                var lineErr = exe.StandardError.ReadLine();
                                textwriter.WriteLine(lineErr);
                                outputFileOnServer.WriteLine(lineErr);
                            }

//                            var lineOut = exe.StandardOutput.ReadToEnd();
                            var lineOut = exe.StandardError.ReadToEnd();
                            textwriter.Write(lineOut);
                            outputFileOnServer.Write(lineOut);
                        });

                        // Reads the standard output
                        string line;
                        while (!exe.HasExited)
                        {
                            line = exe.StandardOutput.ReadLine();
                            textwriter.WriteLine(line);
                            outputFileOnServer.WriteLine(line);
                        }

                        line = exe.StandardOutput.ReadToEnd();
                        textwriter.WriteLine(line);
                        outputFileOnServer.WriteLine(line);

                        //            line = exe.StandardError.ReadToEnd();
                        //           textwriter.Write(line);
                        //        outputFileOnServer.WriteLineAsync(line);

                        // Before returning, let's flush everything
                        textwriter.Flush();
                        outputFileOnServer.Flush();

                        //exe.WaitForExit(); // Why we need it?

                        return(exe.ExitCode);
                    }
                }
            }
            catch (Exception e)
            {
                CloudotLogging.WriteLine("Some exception (of type {0}) happened during the analysis {1}", e.GetType(), this.myId);
                return(-1);
            }
            finally
            {
                // do nothing
            }
        }