public override void Export(IList<BenchmarkReport> reports, IBenchmarkLogger logger, IEnumerable<IBenchmarkResultExtender> resultExtenders = null)
 {
     logger.WriteLine(string.Join(";", columns.Select(c => c.Title)));
     foreach (var report in reports)
         foreach (var run in report.Runs)
             logger.WriteLine(string.Join(";", columns.Select(column => column.GetValue(report, run))));
 }
        public override void Export(IList<BenchmarkReport> reports, IBenchmarkLogger logger, IEnumerable<IBenchmarkResultExtender> resultExtenders = null)
        {
            if(useCodeBlocks)
                logger.WriteLine($"```{codeBlocksSyntax}");
            logger = new BenchmarkLoggerWithPrefix(logger, prefix);
            logger.WriteLineInfo(EnvironmentInfo.GetCurrentInfo().ToFormattedString("Host"));
            logger.NewLine();

            var table = BenchmarkExporterHelper.BuildTable(reports, resultExtenders);
            // If we have Benchmarks with ParametersSets, force the "Method" columns to be displayed, otherwise it doesn't make as much sense
            var columnsToAlwaysShow = 
                (reports.Any(r => r.Benchmark.Task.ParametersSets != null) ? new[] { "Method" } : new string[0]).
                Concat((resultExtenders ?? new IBenchmarkResultExtender[0]).Select(e => e.ColumnName)).ToArray();
            PrintTable(table, logger, columnsToAlwaysShow);

            // TODO: move this logic to an analyser
            var benchmarksWithTroubles = reports.Where(r => !r.GetTargetRuns().Any()).Select(r => r.Benchmark).ToList();
            if (benchmarksWithTroubles.Count > 0)
            {
                logger.NewLine();
                logger.WriteLineError("Benchmarks with troubles:");
                foreach (var benchmarkWithTroubles in benchmarksWithTroubles)
                    logger.WriteLineError("  " + benchmarkWithTroubles.Caption);
            }
        }
Ejemplo n.º 3
0
        public BenchmarkExecResult Execute(BenchmarkBuildResult buildResult, BenchmarkParameters parameters, IBenchmarkDiagnoser diagnoser)
        {
            var exeName = Path.Combine(buildResult.DirectoryPath, "Program.exe");
            var args    = parameters == null ? string.Empty : parameters.ToArgs();

            if (File.Exists(exeName))
            {
                var lines     = new List <string>();
                var startInfo = CreateStartInfo(exeName, args);
                using (var process = Process.Start(startInfo))
                {
                    if (process != null)
                    {
                        process.PriorityClass     = ProcessPriorityClass.High;
                        process.ProcessorAffinity = new IntPtr(2);
                        string line;
                        while ((line = process.StandardOutput.ReadLine()) != null)
                        {
                            logger?.WriteLine(line);
                            if (!line.StartsWith("//") && !string.IsNullOrEmpty(line))
                            {
                                lines.Add(line);
                            }

                            // Wait until we know "Warmup" is happening, and then dissassemble the process
                            if (codeAlreadyExtracted == false && line.StartsWith("// Warmup") && !line.StartsWith("// Warmup (idle)"))
                            {
                                try
                                {
                                    diagnoser.Print(benchmark, process, logger);
                                }
                                finally
                                {
                                    // Always set this, even if something went wrong, otherwise we will try on every run of a benchmark batch
                                    codeAlreadyExtracted = true;
                                }
                            }
                        }
                        if (process.HasExited && process.ExitCode != 0)
                        {
                            if (logger != null)
                            {
                                logger.WriteError(
                                    $"Something bad happened during the execution of {exeName}. Try to run the benchmark again using an AnyCPU application\n");
                            }
                            else
                            {
                                if (exeName.ToLowerInvariant() == "msbuild")
                                {
                                    Console.WriteLine("Build failed");
                                }
                            }
                            return(new BenchmarkExecResult(true, new string[0]));
                        }
                    }
                }
                return(new BenchmarkExecResult(true, lines));
            }
            return(new BenchmarkExecResult(false, new string[0]));
        }
        /// <summary>
        /// Code from http://stackoverflow.com/questions/2057781/is-there-a-way-to-get-the-stacktraces-for-all-threads-in-c-like-java-lang-thre/24315960#24315960
        /// also see http://stackoverflow.com/questions/31633541/clrmd-throws-exception-when-creating-runtime/31745689#31745689
        /// </summary>
        public void PrintCodeForMethod(Benchmark benchmark, Process process, IBenchmarkLogger logger, bool printAssembly, bool printIL, bool printDiagnostics)
        {
            this.process = process;
            this.logger  = logger;

            //Method name format: "BenchmarkDotNet.Samples.Infra.RunFast()" (NOTE: WITHOUT the return type)
            var methodInfo = benchmark.Target.Method;

            fullTypeName = methodInfo.DeclaringType.FullName;

            var methodParams = string.Join(", ", methodInfo.GetParameters().Select(p => p.ParameterType.FullName));

            fullMethodName = $"{fullTypeName}.{methodInfo.Name}({methodParams})";

            logger?.WriteLine($"\nPrinting Code for Method: {fullMethodName}");
            logger?.WriteLine($"\nPrintAssembly={printAssembly}, PrintIL={printIL}");
            logger?.WriteLine($"Attaching to process {Path.GetFileName(process.MainModule.FileName)}, Pid={process.Id}");
            logger?.WriteLine($"Path {process.MainModule.FileName}");
            using (var dataTarget = DataTarget.AttachToProcess(process.Id, 5000, AttachFlag.NonInvasive))
            {
                var runtime = SetupClrRuntime(dataTarget);
                if (printDiagnostics)
                {
                    PrintRuntimeDiagnosticInfo(dataTarget, runtime);
                }

                if (printAssembly == false && printIL == false)
                {
                    return;
                }

                ClrType       @class  = runtime.GetHeap().GetTypeByName(fullTypeName);
                ClrMethod     @method = @class.Methods.Single(m => m.GetFullSignature() == fullMethodName);
                DesktopModule module  = (DesktopModule)@method.Type.Module;
                if (!module.IsPdbLoaded)
                {
                    string pdbLocation = module.TryDownloadPdb(null);
                    if (pdbLocation != null)
                    {
                        module.LoadPdb(pdbLocation);
                    }
                }

                logger?.WriteLine($"Module: {Path.GetFileName(module.Name)}");
                logger?.WriteLine($"Type: {method.Type.Name}");
                logger?.WriteLine($"Method: {method.Name}");

                // TODO work out why this returns locations inside OTHER methods, it's like it doesn't have an upper bound and just keeps going!?
                var ilOffsetLocations = module.GetSourceLocationsForMethod(@method.MetadataToken);

                string   filePath = null;
                string[] lines    = null;
                logger?.WriteLine("");
                for (int i = 0; i < ilOffsetLocations.Count; i++)
                {
                    var location = ilOffsetLocations[i];
                    var ilMaps   = @method.ILOffsetMap.Where(il => il.ILOffset == location.ILOffset).ToList();
                    if (ilMaps.Any() == false)
                    {
                        continue;
                    }

                    if (lines == null || location.SourceLocation.FilePath != filePath)
                    {
                        filePath = location.SourceLocation.FilePath;
                        lines    = File.ReadAllLines(filePath);
                        logger?.WriteLine($"Parsing file {Path.GetFileName(location.SourceLocation.FilePath)}");
                    }

                    PrintLocationAndILMapInfo(@method, location, ilMaps);
                    PrintSourceCode(lines, location);

                    if (printAssembly)
                    {
                        var debugControl = dataTarget.DebuggerInterface as IDebugControl;
                        PrintAssemblyCode(@method, ilMaps, runtime, debugControl);
                    }
                }
            }
        }
 public static void WriteLineError(this IBenchmarkLogger logger, string format, params object[] args)
 {
     logger.WriteLine(BenchmarkLogKind.Error, format, args);
 }
Ejemplo n.º 6
0
 public static void WriteLine(this IBenchmarkLogger logger)
 {
     logger.WriteLine(BenchmarkLogKind.Default, "");
 }