private static void UnzipDataFiles() { 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))); Trace.WriteLine(string.Format("Output Directory: {0}", Path.GetFullPath(OutputDir))); 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.UnpackAchive(); } else { Trace.WriteLine(string.Format("using cached ETL file {0}", etlFilePath)); } Assert.IsTrue(File.Exists(etlFilePath)); } Trace.WriteLine("Finished unzipping data"); }
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()); }
/// <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); } } }