Example #1
0
        private static void UnzipDataFiles()
        {
            if (s_fileUnzipped)
            {
                return;
            }

            Trace.WriteLine(string.Format("Current Directory: {0}", Environment.CurrentDirectory));
            Trace.WriteLine(string.Format("TestDataDir Directory: {0}", Path.GetFullPath(TestDataDir)));
            Trace.WriteLine(string.Format("Unzipped Directory: {0}", Path.GetFullPath(UnZippedDataDir)));

            foreach (var dataFile in Directory.EnumerateFiles(TestDataDir, "*.etl.zip"))
            {
                string etlFilePath = Path.Combine(UnZippedDataDir, Path.GetFileNameWithoutExtension(dataFile));
                if (!File.Exists(etlFilePath) || File.GetLastWriteTimeUtc(etlFilePath) < File.GetLastWriteTimeUtc(dataFile))
                {
                    Trace.WriteLine(string.Format("Unzipping File {0} -> {1}", dataFile, etlFilePath));
                    var zipReader = new ZippedETLReader(dataFile);
                    zipReader.SymbolDirectory = Path.Combine(UnZippedDataDir, "Symbols");
                    zipReader.EtlFileName     = etlFilePath;
                    zipReader.UnpackArchive();
                }
                else
                {
                    Trace.WriteLine(string.Format("using cached ETL file {0}", etlFilePath));
                }
                Assert.True(File.Exists(etlFilePath));
            }
            Trace.WriteLine("Finished unzipping data");
            s_fileUnzipped = true;
        }
Example #2
0
        static void ReadETWFile(AggregateData aggregate, string fileName)
        {
            ZippedETLReader zipReader = new ZippedETLReader(fileName, Console.Out);

            zipReader.UnpackArchive();

            var traceLog = TraceLog.OpenOrConvert(fileName.Substring(0, fileName.Length - 4), new TraceLogOptions()
            {
                ConversionLog = Console.Out
            });
            var evts = traceLog.Events.Filter(e => e.ProviderName.Equals("Microsoft-Build"));
            Dictionary <string, Dictionary <int, double> > startTimes = new Dictionary <string, Dictionary <int, double> >();
            List <Tuple <string, string, double> >         events     = new();

            foreach (var evt in evts.Where(e => e.EventName.Contains("ExecuteTask") || e.EventName.Contains("Target")))
            {
                string key = evt.EventName.Contains("Target") ? "Target," + evt.PayloadValue(evt.PayloadIndex("targetName")) : "Task," + evt.PayloadValue(evt.PayloadIndex("taskName"));
                if (evt.EventName.Contains("Start"))
                {
                    if (startTimes.TryGetValue(key, out Dictionary <int, double>?latest))
                    {
                        latest[evt.ThreadID] = evt.TimeStampRelativeMSec;
                    }
                    else
                    {
                        startTimes.Add(key, new Dictionary <int, double>()
                        {
                            { evt.ThreadID, evt.TimeStampRelativeMSec }
                        });
                    }
                }
                else
                {
                    try
                    {
                        double startTime = startTimes[key][evt.ThreadID];
                        events.Add(Tuple.Create(key.Split(',')[0], key.Split(',')[1], evt.TimeStampRelativeMSec - startTime));
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            events = events.GroupBy(t => t.Item2, (key, enumerable) => enumerable.Aggregate((f, s) => Tuple.Create(f.Item1, f.Item2, f.Item3 + s.Item3))).ToList();
            events.Sort((f, s) => f.Item3 > s.Item3 ? -1 : f.Item3 == s.Item3 ? 0 : 1);
            List <TaskSummary> tasks = new();

            foreach (var evt in events)
            {
                tasks.Add(new(evt.Item2, evt.Item3));
            }

            aggregate.AddBuild(fileName.Substring(0, fileName.Length - 8), tasks);
        }
Example #3
0
        internal static void UnZipIfNecessary(ref string inputFileName, TextWriter log)
        {
            if (inputFileName.EndsWith(".trace.zip", StringComparison.OrdinalIgnoreCase))
            {
                log.WriteLine($"'{inputFileName}' is a linux trace.");
                return;
            }

            var extension = Path.GetExtension(inputFileName);

            if (string.Compare(extension, ".zip", StringComparison.OrdinalIgnoreCase) == 0 ||
                string.Compare(extension, ".vspx", StringComparison.OrdinalIgnoreCase) == 0)
            {
                string unzipedEtlFile;
                if (inputFileName.EndsWith(".etl.zip", StringComparison.OrdinalIgnoreCase))
                {
                    unzipedEtlFile = inputFileName.Substring(0, inputFileName.Length - 4);
                }
                else if (inputFileName.EndsWith(".vspx", StringComparison.OrdinalIgnoreCase))
                {
                    unzipedEtlFile = Path.ChangeExtension(inputFileName, ".etl");
                }
                else
                {
                    throw new ApplicationException("File does not end with the .etl.zip file extension");
                }

                ZippedETLReader etlReader = new ZippedETLReader(inputFileName, log);
                etlReader.EtlFileName = unzipedEtlFile;

                // Figure out where to put the symbols.
                var inputDir = Path.GetDirectoryName(inputFileName);
                if (inputDir.Length == 0)
                {
                    inputDir = ".";
                }

                var symbolsDir = Path.Combine(inputDir, "symbols");
                etlReader.SymbolDirectory = symbolsDir;
                if (!Directory.Exists(symbolsDir))
                {
                    Directory.CreateDirectory(symbolsDir);
                }
                log.WriteLine("Putting symbols in {0}", etlReader.SymbolDirectory);

                etlReader.UnpackArchive();
                inputFileName = unzipedEtlFile;
            }
        }
        /// <summary>
        /// Process the data in 'dataFileName' printing the events and doing delta computation between 'MyFirstEvent'
        /// and 'MySecondEvent'.
        /// </summary>
        static void ProcessData(string dataFileName)
        {
            var zipDataFileName = dataFileName + ".zip";

            Out.WriteLine("**************  Unpacking the ZIP file {0}", zipDataFileName);
            // This will unpack the ETL file as well as unpacks any symbols into  the default
            // symbol cache (the first symbol cache on your _NT_SYMBOL_PATH or %TEMP%\symbols
            // if there is no such symbol cache.    You can override where this goes by
            // setting the SymbolDirectory variable.
            ZippedETLReader zipReader = new ZippedETLReader(zipDataFileName, Out);

            //    zipReader.UnpackAchive();
            Out.WriteLine("Unpacked ETL to {0} Unpacked Symbols to {1}", zipReader.EtlFileName, zipReader.SymbolDirectory);

            Out.WriteLine("**************  Creating a ETLX file for {0}", dataFileName);
            // Note the OpenOrConvert will take an ETL file and generate an ETLX (right next to it) if it is out of date.
            // We TraceLogOptions gives you control over this conversion.  Here we spew the log file to the console
            var traceLog = TraceLog.OpenOrConvert(dataFileName, new TraceLogOptions()
            {
                ConversionLog = Out
            });

            Out.WriteLine("**************  Done converting", Path.GetFileName(traceLog.FilePath));

            // The OS process ID of this process
            var myProcessID = Process.GetCurrentProcess().Id;

            // Find myself in th trace.
            var simpleTraceLogProcess = traceLog.Processes.LastProcessWithID(myProcessID);

            Debug.Assert(simpleTraceLogProcess != null);

            // Resolve symbols for clr and ntdll using the standard Microsoft symbol server path.
            var symbolReader = new SymbolReader(Out, SymbolPath.MicrosoftSymbolServerPath);

            // By default the symbol reader will NOT read PDBs from 'unsafe' locations (like next to the EXE)
            // because hackers might make malicious PDBs.   If you wish ignore this threat, you can override this
            // check to always return 'true' for checking that a PDB is 'safe'.
            symbolReader.SecurityCheck = (path => true);

            foreach (var module in simpleTraceLogProcess.LoadedModules)
            {
                if (module.Name == "clr" || module.Name == "ntdll" || module.Name == "mscorlib.ni")
                {
                    traceLog.CodeAddresses.LookupSymbolsForModule(symbolReader, module.ModuleFile);
                }
            }

            // Source line lookup is verbose, so we don't send it to the console but to srcLookupLog (which we currently ignore)
            var srcLookupLog       = new StringWriter();
            var silentSymbolReader = new SymbolReader(srcLookupLog, SymbolPath.MicrosoftSymbolServerPath);

            silentSymbolReader.Options       = SymbolReaderOptions.CacheOnly; // don't try to look things up on the network for source
            silentSymbolReader.SecurityCheck = (pdbPath) => true;             // for this demo we trust any pdb location.   This lets us find the PDB of the demo itself

            // By default the symbol reader will NOT read PDBs from 'unsafe' locations (like next to the EXE)
            // because hackers might make malicious PDBs.   If you wish ignore this threat, you can override this
            // check to always return 'true' for checking that a PDB is 'safe'.
            silentSymbolReader.SecurityCheck = (path => true);


            Out.WriteLine("******Looking for EXCEPTION EVENTS");
            // Get all the exception events in
            foreach (var exceptionData in (simpleTraceLogProcess.EventsInProcess.ByEventType <ExceptionTraceData>()))
            {
                Out.WriteLine("Found an EXCEPTION event in SimpleTraceLog: Type: {0} Message: {1}", exceptionData.ExceptionType, exceptionData.ExceptionMessage);
                PrintStack(exceptionData.CallStack(), silentSymbolReader);
            }

            Out.WriteLine();
            Out.WriteLine("******Looking for Microsoft-Demos-SimpleMonitor.Stop EVENTS");
            foreach (var data in simpleTraceLogProcess.EventsInProcess)
            {
                if (data.ProviderName == "Microsoft-Demos-SimpleMonitor" && data.EventName == "Stop")
                {
                    Out.WriteLine("Found an EVENTSOURCE event {0} at {1:f3} MSec into trace", data.EventName, data.TimeStampRelativeMSec);
                    PrintStack(data.CallStack(), silentSymbolReader);
                }
            }
        }
        public ICallTreeDataProvider Get()
        {
            var queryString = this.httpRequest.Query;

            string filename  = queryString["filename"];
            string stacktype = queryString["stacktype"];

            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }

            if (string.IsNullOrEmpty(stacktype))
            {
                throw new ArgumentNullException("stacktype");
            }

            /* symbols and sources related parameters */
            string     sympathStr         = (string)queryString["sympath"] ?? SymbolPath.MicrosoftSymbolServerPath;
            SymbolPath symPath            = new SymbolPath(sympathStr);
            string     defaultSymbolCache = symPath.DefaultSymbolCache();

            // Normalize the symbol path.
            symPath    = symPath.InsureHasCache(defaultSymbolCache);
            sympathStr = symPath.ToString();

            string srcpath = (string)queryString["srcpath"];
            //TODO FIX NOW: Dont spew to the Console, send it back to the client.
            SymbolReader symbolReader = new SymbolReader(Console.Out, sympathStr);

            if (srcpath != null)
            {
                symbolReader.SourcePath = srcpath;
            }

            string modulePatStr = (string)queryString["symLookupPats"] ?? @"^(clr|ntoskrnl|ntdll|.*\.ni)";

            /* filtering parameters */
            string start     = (string)queryString["start"] ?? string.Empty;
            string end       = (string)queryString["end"] ?? string.Empty;
            string incpats   = (string)queryString["incpats"] ?? string.Empty;
            string excpats   = (string)queryString["excpats"] ?? string.Empty;
            string foldpats  = (string)queryString["foldpats"] ?? string.Empty;
            string grouppats = (string)queryString["grouppats"] ?? string.Empty;
            string foldpct   = (string)queryString["foldpct"] ?? string.Empty;
            string find      = (string)queryString["find"] ?? string.Empty;

            EtlxFile etlxFile;

            // Do it twice so that XXX.etl.zip becomes XXX.
            string etlxFilePath = Path.ChangeExtension(Path.ChangeExtension(filename, null), ".etlx");

            lock (this.etlxCache)
            {
                if (this.etlxCache.TryGetValue(filename, out etlxFile))
                {
                    if (etlxFile == null)
                    {
                        throw new ArgumentNullException("etlxFile");
                    }
                }
                else
                {
                    etlxFile = new EtlxFile(filename)
                    {
                        Pending = true
                    };
                    this.etlxCache.Set(filename, etlxFile, this.cacheExpirationTime);
                }
            }

            lock (etlxFile)
            {
                if (etlxFile.Pending)
                {
                    if (!File.Exists(etlxFilePath))
                    {
                        // if it's a zip file
                        if (string.Equals(Path.GetExtension(filename), ".zip", StringComparison.OrdinalIgnoreCase))
                        {
                            //TODO FIX NOW: Dont spew to the Console, send it back to the client.
                            ZippedETLReader reader = new ZippedETLReader(filename, Console.Out);
                            reader.SymbolDirectory = defaultSymbolCache;
                            reader.EtlFileName     = Path.ChangeExtension(etlxFilePath, etlExtension);
                            reader.UnpackAchive();
                            TraceLog.CreateFromEventTraceLogFile(reader.EtlFileName, etlxFilePath);
                        }
                        else
                        {
                            TraceLog.CreateFromEventTraceLogFile(filename, etlxFilePath);
                        }
                    }

                    etlxFile.TraceLog = TraceLog.OpenOrConvert(etlxFilePath);
                    etlxFile.Pending  = false;
                }

                Regex modulePat = new Regex(modulePatStr, RegexOptions.IgnoreCase);
                foreach (var moduleFile in etlxFile.TraceLog.ModuleFiles)
                {
                    if (modulePat.IsMatch(moduleFile.Name))
                    {
                        etlxFile.TraceLog.CodeAddresses.LookupSymbolsForModule(symbolReader, moduleFile);
                    }
                }
            }

            StackViewerSession stackViewerSession;

            lock (this.stackViewerSessionCache)
            {
                var filterParams = new FilterParams {
                    Name = filename + stacktype, StartTimeRelativeMSec = start, EndTimeRelativeMSec = end, MinInclusiveTimePercent = foldpct, FoldRegExs = foldpats, IncludeRegExs = incpats, ExcludeRegExs = excpats, GroupRegExs = grouppats
                };
                var keyBuilder = new StringBuilder();
                keyBuilder.Append(filterParams.Name).Append("?" + filterParams.StartTimeRelativeMSec).Append("?" + filterParams.EndTimeRelativeMSec).Append("?" + filterParams.MinInclusiveTimePercent).Append("?" + filterParams.FoldRegExs).Append("?" + filterParams.IncludeRegExs).Append("?" + filterParams.ExcludeRegExs).Append("?" + filterParams.GroupRegExs).Append("?" + find);

                var stackViewerKey = keyBuilder.ToString();
                if (this.stackViewerSessionCache.TryGetValue(stackViewerKey, out stackViewerSession))
                {
                    if (stackViewerSession == null)
                    {
                        throw new ArgumentNullException("stackViewerSession");
                    }
                }
                else
                {
                    stackViewerSession = new StackViewerSession(filename, stacktype, etlxFile.TraceLog, filterParams, symbolReader);
                    this.stackViewerSessionCache.Set(stackViewerKey, stackViewerSession, cacheExpirationTime);
                }
            }

            lock (stackViewerSession)
            {
                if (stackViewerSession.Pending)
                {
                    stackViewerSession.InitializeDataProvider();
                    stackViewerSession.Pending = false;
                }
            }

            return(stackViewerSession.GetDataProvider());
        }