Beispiel #1
0
        private void AddMSSymbolsClicked(object sender, RoutedEventArgs e)
        {
            var symPath = new SymbolPath(GetValue());

            symPath.Add("SRV*http://msdl.microsoft.com/download/symbols");
            SymbolPathTextBox.Text = symPath.InsureHasCache(symPath.DefaultSymbolCache()).CacheFirst().ToString();
            GetValue();
        }
        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());
        }
Beispiel #3
0
        public static SymbolReader GetSymbolReader(string additionalPath, string etlFilePath = null, SymbolReaderOptions symbolFlags = SymbolReaderOptions.None)
        {
            string localSymbolPath = @"D:\home\data\DaaS\symbols";

            if (!Directory.Exists(@"D:\home\data\DaaS"))
            {
                localSymbolPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "symbols");
            }
            SymbolPath symPath = new SymbolPath(string.Format(@"srv*{0}*http://msdl.microsoft.com/download/symbols", localSymbolPath));

            if ((symbolFlags & SymbolReaderOptions.CacheOnly) != 0)
            {
                symPath = new SymbolPath("SRV*" + symPath.DefaultSymbolCache());
            }

            var assemblyDir = Assembly.GetEntryAssembly().Location;

            //
            // This is required if we ever don't end up caching the symbols of
            // our images on the symbol server. In those cases, the DAAS package
            // should be updated with the Symbols folder for ngen binaries.
            //
            var daasPath       = assemblyDir.Substring(0, assemblyDir.IndexOf("bin", StringComparison.InvariantCultureIgnoreCase));
            var daasSymbolPath = Path.Combine(daasPath, "Symbols");

            if (!Directory.Exists(daasSymbolPath))
            {
                daasSymbolPath = "";
            }

            symPath.Insert(@"srv*d:\NdpCorePdb*");
            symPath.Insert(@"srv*D:\home\data\DaaS\symbols*" + daasSymbolPath);

            string localSymDir = symPath.DefaultSymbolCache();

            if (etlFilePath != null)
            {
                // Add the directory where the file resides and a 'symbols' subdirectory
                var filePathDir = Path.GetDirectoryName(etlFilePath);
                if (filePathDir.Length != 0)
                {
                    // Then the directory where the .ETL file lives.
                    symPath.Insert(filePathDir);

                    // If there is a 'symbols' directory next to the data file, look for symbols there
                    // as well.   Note that we also put copies of any symbols here as well (see below)
                    string potentiallocalSymDir = Path.Combine(filePathDir, "symbols");
                    if (Directory.Exists(potentiallocalSymDir))
                    {
                        symPath.Insert(potentiallocalSymDir);
                        symPath.Insert("SRV*" + potentiallocalSymDir);
                        localSymDir = potentiallocalSymDir;
                    }

                    // WPR conventions add any .etl.ngenPDB directory to the path too.   has higher priority still.
                    var wprSymDir = etlFilePath + ".NGENPDB";
                    if (Directory.Exists(wprSymDir))
                    {
                        symPath.Insert("SRV*" + wprSymDir);
                    }
                    else
                    {
                        // I have now seen both conventions .etl.ngenpdb and .ngenpdb, so look for both.
                        wprSymDir = Path.ChangeExtension(etlFilePath, ".NGENPDB");
                        if (Directory.Exists(wprSymDir))
                        {
                            symPath.Insert("SRV*" + wprSymDir);
                        }
                    }
                    // VS uses .NGENPDBS as a convention.
                    wprSymDir = etlFilePath + ".NGENPDBS";
                    if (Directory.Exists(wprSymDir))
                    {
                        symPath.Insert("SRV*" + wprSymDir);
                    }

                    if (Directory.Exists(additionalPath))
                    {
                        symPath.Insert(additionalPath);
                    }
                }
            }
            DaaS.Logger.LogInfo("Symbol reader _NT_SYMBOL_PATH=");
            foreach (var element in symPath.Elements)
            {
                DaaS.Logger.LogInfo($"    {element};");
            }

            TextWriter textWriter = null;

            if (Trace.Listeners["TextWriterTraceListener"] != null)
            {
                var textWriterListener = Trace.Listeners["TextWriterTraceListener"] as System.Diagnostics.TextWriterTraceListener;
                textWriter = textWriterListener.Writer;
            }
            else
            {
                textWriter = Console.Out;
            }

            SymbolReader ret = new SymbolReader(textWriter, symPath.ToString())
            {
                Options = symbolFlags
            };

            ret.SecurityCheck = (pdbFile => true);

            if (localSymDir != null)
            {
                ret.OnSymbolFileFound += (pdbPath, pdbGuid, pdbAge) => CacheInLocalSymDir(localSymDir, pdbPath, pdbGuid, pdbAge, Console.Out);
            }

            return(ret);
        }