示例#1
0
 public StackView(TraceLog traceLog, StackSource stackSource, SymbolReader symbolReader)
 {
     _traceLog       = traceLog;
     _rawStackSource = stackSource;
     _symbolReader   = symbolReader;
     LookupWarmNGENSymbols();
 }
 public ExceptionViewModel(ExceptionTraceData data, TraceCallStack stack, SymbolReader reader)
 {
     _data       = data;
     _stack      = stack;
     _reader     = reader;
     ProcessName = GetProcessName();
 }
示例#3
0
        static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream)
        {
            SymbolReader symReader = null;
            bool         error     = true;

            try {
                if (!pdbContext.HasDebugInfo)
                {
                    return(null);
                }

                if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && pdbStream is not null && IsWindowsPdb(pdbStream.CreateReader()))
                {
                    symReader = Dss.SymbolReaderWriterFactory.Create(pdbContext, metadata, pdbStream);
                }
                else
                {
                    symReader = CreateManaged(pdbContext, metadata, pdbStream);
                }

                if (symReader is not null)
                {
                    error = false;
                    return(symReader);
                }
            }
        /// <summary>
        /// Print data.  Note that this method is called FROM DIFFERNET THREADS which means you need to properly
        /// lock any read-write data you access.   It turns out Out.Writeline is already thread safe so
        /// there is nothing I have to do in this case.
        /// </summary>
        private static void Print(TraceEvent data, SymbolReader symbolReader)
        {
            // There are a lot of data collection start on entry that I don't want to see (but often they are quite handy
            if (data.Opcode == TraceEventOpcode.DataCollectionStart)
            {
                return;
            }
            // V3.5 runtimes don't log the stack and in fact don't event log the exception name (it shows up as an empty string)
            // Just ignore these as they are not that interesting.
            if (data is ExceptionTraceData && ((ExceptionTraceData)data).ExceptionType.Length == 0)
            {
                return;
            }

            if (!data.ProcessName.Contains("Samples"))
            {
                return;
            }

            Out.WriteLine("EVENT: {0}", data.ToString());
            var callStack = data.CallStack();

            if (callStack != null)
            {
                // Because symbol lookup is complex, error prone, and expensive TraceLog requires you to be explicit.
                // Here we look up names in this call stack using the symbol reader.
                ResolveNativeCode(callStack, symbolReader);
                Out.WriteLine("CALLSTACK: {0}", callStack.ToString());
            }
        }
示例#5
0
        private static void ConvertToSpeedscope(string fileToConvert)
        {
            var symbolReader = new SymbolReader(System.IO.TextWriter.Null)
            {
                SymbolPath = SymbolPath.MicrosoftSymbolServerPath
            };
            var etlxFilePath = TraceLog.CreateFromEventPipeDataFile(fileToConvert);

            var eventLog = new TraceLog(etlxFilePath);

            try
            {
                var stackSource = new MutableTraceEventStackSource(eventLog)
                {
                    OnlyManagedCodeStacks = true // EventPipe currently only has managed code stacks.
                };

                var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader);
                computer.GenerateThreadTimeStacks(stackSource);

                var speedScopeFilePath = Path.ChangeExtension(fileToConvert, "speedscope.json");

                SpeedScopeStackSourceWriter.WriteStackViewAsJson(stackSource, speedScopeFilePath);
            }
            finally
            {
                eventLog.Dispose();

                if (File.Exists(etlxFilePath))
                {
                    File.Delete(etlxFilePath);
                }
            }
        }
        public AllocationTickMemoryProfiler(TraceEventSession session, int pid, ProcessAllocationInfo allocations, bool verbose = false)
        {
            if (session == null)
            {
                throw new NullReferenceException(nameof(session));
            }
            _session = session;

            if (allocations == null)
            {
                throw new NullReferenceException(nameof(allocations));
            }
            _allocations = allocations;

            _pid     = pid;
            _verbose = verbose;

            _symbolLookupMessages = new StringWriter();

            // By default a symbol Reader uses whatever is in the _NT_SYMBOL_PATH variable.  However you can override
            // if you wish by passing it to the SymbolReader constructor.  Since we want this to work even if you
            // have not set an _NT_SYMBOL_PATH, so we add the Microsoft default symbol server path to be sure/
            var symbolPath = new SymbolPath(SymbolPath.SymbolPathFromEnvironment).Add(SymbolPath.MicrosoftSymbolServerPath);

            _symbolReader = new SymbolReader(_symbolLookupMessages, symbolPath.ToString());

            // 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);
        }
示例#7
0
        private static void PrintStack(TraceCallStack callStack, SymbolReader symbolReader)
        {
            Out.WriteLine("STACKTRACE:");
            while (callStack != null)
            {
                var method = callStack.CodeAddress.Method;
                var module = callStack.CodeAddress.ModuleFile;
                if (method != null)
                {
                    // see if we can get line number information
                    var lineInfo       = "";
                    var sourceLocation = callStack.CodeAddress.GetSourceLine(symbolReader);
                    if (sourceLocation != null)
                    {
                        lineInfo = string.Format("  AT: {0}({1})", Path.GetFileName(sourceLocation.SourceFile.BuildTimeFilePath), sourceLocation.LineNumber);
                    }

                    Out.WriteLine("    Method: {0}!{1}{2}", module.Name, method.FullMethodName, lineInfo);
                }
                else if (module != null)
                {
                    Out.WriteLine("    Module: {0}!0x{1:x}", module.Name, callStack.CodeAddress.Address);
                }
                else
                {
                    Out.WriteLine("    ?!0x{0:x}", callStack.CodeAddress.Address);
                }

                callStack = callStack.Caller;
            }
        }
示例#8
0
 internal AutomatedAnalysisExecutionContext(TraceLog traceLog, TextWriter textLog, SymbolReader symbolReader, AutomatedAnalysisIssueCollection issues)
 {
     TraceLog     = traceLog;
     TextLog      = textLog;
     SymbolReader = symbolReader;
     Issues       = issues;
 }
示例#9
0
        // Method copied from https://github.com/dotnet/diagnostics/blob/2c23d3265dd8f642a8d6cf4bb8a135a5ff8b00c2/src/Tools/dotnet-trace/TraceFileFormatConverter.cs#L64
        private static void ConvertToSpeedscope(string fileToConvert, string outputFilename, bool continueOnError = false)
        {
            var etlxFilePath = TraceLog.CreateFromEventPipeDataFile(fileToConvert, null, new TraceLogOptions()
            {
                ContinueOnError = continueOnError
            });

            using (var symbolReader = new SymbolReader(System.IO.TextWriter.Null)
            {
                SymbolPath = SymbolPath.MicrosoftSymbolServerPath
            })
                using (var eventLog = new TraceLog(etlxFilePath))
                {
                    var stackSource = new MutableTraceEventStackSource(eventLog)
                    {
                        OnlyManagedCodeStacks = true // EventPipe currently only has managed code stacks.
                    };

                    var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader)
                    {
                        IncludeEventSourceEvents = false // SpeedScope handles only CPU samples, events are not supported
                    };
                    computer.GenerateThreadTimeStacks(stackSource);

                    SpeedScopeStackSourceWriter.WriteStackViewAsJson(stackSource, outputFilename);
                }

            if (File.Exists(etlxFilePath))
            {
                File.Delete(etlxFilePath);
            }
        }
示例#10
0
        public StackViewerSession(string filename, string stacktype, TraceLog tracelog, FilterParams filterParams, SymbolReader reader)
        {
            if (filename == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(filename));
            }

            if (stacktype == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(stacktype));
            }

            if (tracelog == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(tracelog));
            }

            if (filterParams == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(filterParams));
            }

            if (reader == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(reader));
            }

            this.Filename     = filename;
            this.StackType    = stacktype;
            this.FilterParams = filterParams;
            this.TraceLog     = tracelog;
            this.reader       = reader;
            this.Pending      = true;
        }
        private static void ConvertToSpeedscope(string fileToConvert, string outputFilename)
        {
            var etlxFilePath = TraceLog.CreateFromEventPipeDataFile(fileToConvert);

            using (var symbolReader = new SymbolReader(System.IO.TextWriter.Null)
            {
                SymbolPath = SymbolPath.MicrosoftSymbolServerPath
            })
                using (var eventLog = new TraceLog(etlxFilePath))
                {
                    var stackSource = new MutableTraceEventStackSource(eventLog)
                    {
                        OnlyManagedCodeStacks = true // EventPipe currently only has managed code stacks.
                    };

                    var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader);
                    computer.GenerateThreadTimeStacks(stackSource);

                    SpeedScopeStackSourceWriter.WriteStackViewAsJson(stackSource, outputFilename);
                }

            if (File.Exists(etlxFilePath))
            {
                File.Delete(etlxFilePath);
            }
        }
示例#12
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                Debug.Assert(!string.IsNullOrEmpty(clrInfo.DacInfo.FileName));
                var    analyzeContext = _serviceProvider.GetService <AnalyzeContext>();
                string dacFilePath    = null;
                if (!string.IsNullOrEmpty(analyzeContext.RuntimeModuleDirectory))
                {
                    dacFilePath = Path.Combine(analyzeContext.RuntimeModuleDirectory, clrInfo.DacInfo.FileName);
                    if (File.Exists(dacFilePath))
                    {
                        _dacFilePath = dacFilePath;
                    }
                }
                if (_dacFilePath == null)
                {
                    dacFilePath = clrInfo.LocalMatchingDac;
                    if (!string.IsNullOrEmpty(dacFilePath) && File.Exists(dacFilePath))
                    {
                        _dacFilePath = dacFilePath;
                    }
                    else if (SymbolReader.IsSymbolStoreEnabled())
                    {
                        string dacFileName = Path.GetFileName(dacFilePath ?? clrInfo.DacInfo.FileName);
                        if (dacFileName != null)
                        {
                            SymbolStoreKey key = null;

                            if (clrInfo.ModuleInfo.BuildId != null)
                            {
                                IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                    KeyTypeFlags.DacDbiKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                                key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
                            }
                            else
                            {
                                // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                                key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                            }

                            if (key != null)
                            {
                                // Now download the DAC module from the symbol server
                                _dacFilePath = SymbolReader.GetSymbolFile(key);
                            }
                        }
                    }

                    if (_dacFilePath == null)
                    {
                        throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                    }
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
示例#13
0
        /// <summary>
        /// Looks up symbols for all modules that have an inclusive count >= minCount.
        /// stackSource, if given, can be used to be the filter.  If null, 'this' is used.
        /// If stackSource is given, it needs to use the same indexes for frames as 'this'
        /// </summary>
        public void LookupWarmSymbols(int minCount, SymbolReader reader, StackSource stackSource = null)
        {
            if (stackSource == null)
            {
                stackSource = this;
            }

            Debug.Assert(stackSource.CallFrameIndexLimit == this.CallFrameIndexLimit);
            Debug.Assert(stackSource.CallStackIndexLimit == this.CallStackIndexLimit);

            reader.Log.WriteLine("Resolving all symbols for modules with inclusive times > {0}", minCount);
            if ((reader.Flags & SymbolReaderFlags.CacheOnly) != 0)
            {
                reader.Log.WriteLine("Cache-Only set: will only look on the local machine.");
            }

            // Get a list of all the unique frames.   We also keep track of unique stacks for efficiency
            var stackModuleLists = new ModuleList[stackSource.CallStackIndexLimit];
            var stackCounts      = new int[stackSource.CallStackIndexLimit];
            var totalCount       = 0;

            // Compute for each stack, the set of inclusive modules for that stack
            stackSource.ProduceSamples(delegate(StackSourceSample sample)
            {
                stackCounts[(int)sample.StackIndex]++;
                totalCount++;
            });
            reader.Log.WriteLine("Got a total of {0} samples", totalCount);

            // for each stack in the trace, find the list of modules for that stack
            var moduleCounts = new int[TraceLog.ModuleFiles.MaxModuleFileIndex];

            for (int i = 0; i < stackCounts.Length; i++)
            {
                var count = stackCounts[i];
                if (count > 0)
                {
                    var modules = GetModulesForStack(stackModuleLists, (StackSourceCallStackIndex)i);
                    // Update the counts for each module in that stack.
                    while (modules != null)
                    {
                        moduleCounts[(int)modules.Module.ModuleFileIndex] += count;
                        modules = modules.Next;
                    }
                }
            }

            // Now that we have an list of the inclusive counts of all frames.  Find all stacks that meet the threshold
            for (int i = 0; i < moduleCounts.Length; i++)
            {
                if (moduleCounts[i] >= minCount)
                {
                    var moduleFile = TraceLog.ModuleFiles[(ModuleFileIndex)i];
                    reader.Log.WriteLine("Resolving symbols (count={0}) for module {1} ", moduleCounts[i], moduleFile.FilePath);
                    TraceLog.CallStacks.CodeAddresses.LookupSymbolsForModule(reader, moduleFile);
                }
            }
            reader.Log.WriteLine("Done Resolving all symbols for modules with inclusive times > {0}", minCount);
        }
示例#14
0
    public void SymbolsTest()
    {
        var m = new SymbolReader(@"C:\Symbols\coreclr.pdb");

        var s = m.GetSymbol("g_pGCHeap");

        Assert.NotNull(s);
    }
示例#15
0
        public void ValidCurrencySymbolTests(string currency)
        {
            // When
            bool actualResults = SymbolReader.IsSymbolValid(currency);

            // Then
            Assert.True(actualResults);
        }
示例#16
0
        public PortableSymbolModule(SymbolReader reader, Stream stream, string pdbFileName = "") : base(reader, pdbFileName)
        {
            _stream   = stream;
            _provider = MetadataReaderProvider.FromPortablePdbStream(_stream);
            _metaData = _provider.GetMetadataReader();

            InitializeFileToUrlMap();
        }
示例#17
0
 /// <summary>
 /// Attempts to download/retrieve from cache the key.
 /// </summary>
 /// <param name="key">index of the file to retrieve</param>
 /// <returns>stream or null</returns>
 public SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
 {
     if (IsSymbolStoreEnabled)
     {
         return(SymbolReader.GetSymbolStoreFile(key));
     }
     return(null);
 }
示例#18
0
        /// <summary>
        /// Process the data in 'dataFileName' printing the events and doing delta computation between 'MyFirstEvent'
        /// and 'MySecondEvent'.
        /// </summary>
        static void ProcessData(string dataFileName)
        {
            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);

            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

            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);
                }
            }
        }
示例#19
0
        public SourceLocation GetSourceLine(StackSourceFrameIndex frameIndex, SymbolReader reader)
        {
            uint codeAddressIndex = (uint)frameIndex - (uint)StackSourceFrameIndex.Start;

            if (codeAddressIndex >= m_log.CodeAddresses.MaxCodeAddressIndex)
            {
                return(null);
            }
            return(m_log.CodeAddresses.GetSourceLine(reader, (CodeAddressIndex)codeAddressIndex));
        }
示例#20
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                string dac = clrInfo.LocalMatchingDac;
                if (dac != null && File.Exists(dac))
                {
                    _dacFilePath = dac;
                }
                else if (SymbolReader.IsSymbolStoreEnabled())
                {
                    string dacFileName = Path.GetFileName(dac ?? clrInfo.DacInfo.FileName);
                    if (dacFileName != null)
                    {
                        SymbolStoreKey key = null;

                        if (clrInfo.ModuleInfo.BuildId != null)
                        {
                            IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                            key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);

                            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                // We are opening a Linux dump on Windows
                                // We need to use the Windows index and filename
                                key = new SymbolStoreKey(key.Index.Replace("libmscordaccore.so", "mscordaccore.dll"),
                                                         key.FullPathName.Replace("libmscordaccore.so", "mscordaccore.dll"),
                                                         key.IsClrSpecialFile,
                                                         key.PdbChecksums);
                            }
                        }
                        else
                        {
                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                        }

                        if (key != null)
                        {
                            // Now download the DAC module from the symbol server
                            _dacFilePath = SymbolReader.GetSymbolFile(key);
                        }
                    }
                }

                if (_dacFilePath == null)
                {
                    throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
示例#21
0
        public static void Main(string [] args)
        {
            var EG           = Test3();
            var expansionRun = new ExpansionsionRun(EG);
            var EG2          = expansionRun.After;
            var c            = new FromEbnfToBnf_ByCopying(EG2);
            var text         = new SymbolReader("cad");
            var pc           = new RecursiveDescentParser(text);
            var res          = pc.RecusiveDescent(c.Bnf ["S"]);

            Console.WriteLine(res);
        }
示例#22
0
        SymbolModule FindPdbForModule(ModuleInfo module)
        {
            if (module == null)
            {
                return(null);
            }

            string pdbName;
            Guid   pdbGuid;
            int    rev;

            using (PEFile pefile = new PEFile(new ReadVirtualStream(m_dataReader, (long)module.ImageBase, (long)module.FileSize), true))
                if (!pefile.GetPdbSignature(out pdbName, out pdbGuid, out rev))
                {
                    return(null);
                }

            if (!File.Exists(pdbName))
            {
                ISymbolNotification notification = DefaultSymbolNotification ?? new NullSymbolNotification();
                pdbName = Path.GetFileName(pdbName);
                pdbName = SymbolReader.FindSymbolFilePath(pdbName, pdbGuid, rev, notification);

                if (string.IsNullOrEmpty(pdbName) || !File.Exists(pdbName))
                {
                    return(null);
                }
            }

            if (pdbName == null)
            {
                m_symbols[module] = null;
                return(null);
            }

            SymbolModule symbols = null;

            try
            {
                symbols           = new SymbolModule(SymbolReader, pdbName);
                m_symbols[module] = symbols;
            }
            catch
            {
                m_symbols[module] = null;
                return(null);
            }

            return(symbols);
        }
示例#23
0
        public ProcessContext(AutomatedAnalysisExecutionContext executionContext, AutomatedAnalysisTraceProcess process)
        {
            _executionContext        = executionContext;
            AutomatedAnalysisProcess = process;
            AutomatedAnalysisTraceLog traceLog = executionContext.Trace as AutomatedAnalysisTraceLog;

            if (traceLog != null)
            {
                Process = traceLog.TraceLog.Processes[(ProcessIndex)process.UniqueID];
            }

            Issues        = executionContext.Issues[process];
            _symbolReader = executionContext.SymbolReader;
        }
示例#24
0
    public static MemoryGraph Create(string dllPath, SymbolReader symbolReader)
    {
        var ret = new MemoryGraph(1000);

        string pdbPath = symbolReader.FindSymbolFilePathForModule(dllPath);

        symbolReader.Log.WriteLine("Got PDB path {0}", pdbPath);

        NativeSymbolModule module  = symbolReader.OpenNativeSymbolFile(pdbPath);
        List <Symbol>      symbols = new List <Symbol>();

        AddAllChildren(symbols, module.GlobalSymbol);

        symbols.Sort();

        /****** Make a graph out of the symbols ******/
        // Put all nodes under this root.
        var rootChildren = new GrowableArray <NodeIndex>(1000);

        // Create a node for each symbol
        uint   lastRVA  = 0;
        string lastName = "Header";
        var    empty    = new GrowableArray <NodeIndex>();

        foreach (var symbol in symbols)
        {
            var symRVA   = symbol.RVA;
            int lastSize = (int)symRVA - (int)lastRVA;

            NodeTypeIndex typeIdx = ret.CreateType(lastName, null, lastSize);
            NodeIndex     nodeIdx = ret.CreateNode();
            ret.SetNode(nodeIdx, typeIdx, lastSize, empty);
            rootChildren.Add(nodeIdx);

            lastName = symbol.Name;
            lastRVA  = symRVA;
        }
        // TODO FIX NOW dropping the last symbol.

        // Create the root node.
        NodeIndex     rootIdx     = ret.CreateNode();
        NodeTypeIndex rootTypeIdx = ret.CreateType("METHODS");

        ret.SetNode(rootIdx, rootTypeIdx, 0, rootChildren);
        ret.RootIndex = rootIdx;

        ret.AllowReading();

        return(ret);
    }
示例#25
0
        static void ProcessData(string dataFileName, string processName)
        {
            Out.WriteLine("**************  Creating a ETLX file for {0}", dataFileName);
            var traceLog = TraceLog.OpenOrConvert(dataFileName, new TraceLogOptions()
            {
                ConversionLog = Out
            });

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

            var simpleTraceLogProcess = traceLog.Processes.LastProcessWithName(processName);

            Debug.Assert(simpleTraceLogProcess != null);

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

            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

            //Out.WriteLine("******Looking for SAMPLE PROFILE EVENTS");
            //int count = 0;
            //foreach (var sample in simpleTraceLogProcess.EventsInProcess.ByEventType<SampledProfileTraceData>())
            //{
            //    ++count;
            //    PrintStack(sample.CallStack(), silentSymbolReader);
            //}
            //Out.WriteLine("******TOTAL {0} SAMPLE PROFILE EVENTS", count);
            //Out.WriteLine();

            Out.WriteLine("******Looking for EXCEPTION EVENTS");
            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();
        }
        private static void PrintStack(TraceCallStack callStack, SymbolReader symbolReader)
        {
            Out.WriteLine("STACKTRACE:");
            while (callStack != null)
            {
                var method = callStack.CodeAddress.Method;
                var module = callStack.CodeAddress.ModuleFile;
                if (method != null)
                {
                    // see if we can get line number information
                    var lineInfo = "";
                    var sourceLocation = callStack.CodeAddress.GetSourceLine(symbolReader);
                    if (sourceLocation != null)
                        lineInfo = string.Format("  AT: {0}({1})", Path.GetFileName(sourceLocation.SourceFile.BuildTimeFilePath), sourceLocation.LineNumber);

                    Out.WriteLine("    Method: {0}!{1}{2}", module.Name, method.FullMethodName, lineInfo);
                }
                else if (module != null)
                    Out.WriteLine("    Module: {0}!0x{1:x}", module.Name, callStack.CodeAddress.Address);
                else
                    Out.WriteLine("    ?!0x{0:x}", callStack.CodeAddress.Address);

                callStack = callStack.Caller;
            }
        }
        /// <summary>
        /// Process the data in 'dataFileName' printing the events and doing delta computation between 'MyFirstEvent'
        /// and 'MySecondEvent'.  
        /// </summary>
        static void ProcessData(string dataFileName)
        {
            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);
            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

            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);
                }
            }
        }
        /// <summary>
        /// Print data.  Note that this method is called FROM DIFFERNET THREADS which means you need to properly
        /// lock any read-write data you access.   It turns out Out.Writeline is already thread safe so
        /// there is nothing I have to do in this case. 
        /// </summary>
        static void Print(TraceEvent data, SymbolReader symbolReader)
        {
            // There are a lot of data collection start on entry that I don't want to see (but often they are quite handy
            if (data.Opcode == TraceEventOpcode.DataCollectionStart)
                return;
            // V3.5 runtimes don't log the stack and in fact don't event log the exception name (it shows up as an empty string)
            // Just ignore these as they are not that interesting. 
            if (data is ExceptionTraceData && ((ExceptionTraceData) data).ExceptionType.Length == 0)
                return;

            Out.WriteLine("EVENT: {0}", data.ToString());
            var callStack = data.CallStack();
            if (callStack != null)
            {
                // Because symbol lookup is complex, error prone, and expensive TraceLog requires you to be explicit.  
                // Here we look up names in this call stack using the symbol reader.  
                ResolveNativeCode(callStack, symbolReader);
                Out.WriteLine("CALLSTACK: {0}", callStack.ToString());
            }
        }
 /// <summary>
 /// Because it is expensive and often unnecessary, lookup of native symbols needs to be explicitly requested.  
 /// Here we do this for every frame in the stack.     Note that this is not needed for JIT compiled managed code. 
 /// </summary>
 static private void ResolveNativeCode(TraceCallStack callStack, SymbolReader symbolReader)
 {
     while (callStack != null)
     {
         var codeAddress = callStack.CodeAddress;
         if (codeAddress.Method == null)
         {
             var moduleFile = codeAddress.ModuleFile;
             if (moduleFile == null)
                 Trace.WriteLine(string.Format("Could not find module for Address 0x{0:x}", codeAddress.Address));
             else
                 codeAddress.CodeAddresses.LookupSymbolsForModule(symbolReader, moduleFile);
         }
         callStack = callStack.Caller;
     }
 }
        public static void Run()
        {
            var monitoringTimeSec = 10;

            Out.WriteLine("******************** RealTimeTraceLog DEMO (win8) ********************");
            Out.WriteLine("This program Shows how to use the real-time support in TraceLog");
            Out.WriteLine("We do this by showing how to monitor exceptions in real time ");
            Out.WriteLine();
            Out.WriteLine("This code depends on a Feature of Windows 8.1 (combined user and kernel sessions)");
            Out.WriteLine();
            Out.WriteLine("Note that this support is currently experimental and subject to change");
            Out.WriteLine();
            Out.WriteLine("Monitoring .NET Module load and Exception events (with stacks).");
            Out.WriteLine("Run some managed code (ideally that has exceptions) while the monitor is running.");
            Out.WriteLine();

            if (Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor < 62)
            {
                Out.WriteLine("This demo only works on Win8 / Win 2012 and above)");
                return;
            }

           TraceEventSession session = null;

            // Set up Ctrl-C to stop both user mode and kernel mode sessions
            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs cancelArgs) =>
            {
                if (session != null)
                    session.Dispose();
                cancelArgs.Cancel = true;
            };

            // Cause an exception to be thrown a few seconds in (so we have something interesting to look at)
            var exceptionGeneationTask = Task.Factory.StartNew(delegate
            {
                Thread.Sleep(3000);
                ThrowException();
            });

            Timer timer = null;

            // Create the new session to receive the events.  
            // Because we are on Win 8 this single session can handle both kernel and non-kernel providers.  
            using (session = new TraceEventSession("TraceLogSession"))
            {
                // Enable the events we care about for the kernel
                // For this instant the session will buffer any incoming events.  
                // Enabling kernel events must be done before anything else.   
                // This will fail on Win7.    
                //
                // Note that if you turn on the KernelTraceEventParser.Keywords.Profile, you can also get stacks for CPU sampling 
                // (every millisecond).  (You can use the traceLogSource.Kernel.PerfInfoSample callback).  
                Out.WriteLine("Enabling Image load, Process and Thread events.  These are needed to look up native method names.");
                session.EnableKernelProvider(
                    // KernelTraceEventParser.Keywords.Profile |            // If you want CPU sampling events 
                    // KernelTraceEventParser.Keywords.ContextSwitch |      // If you want context switch events
                    // KernelTraceEventParser.Keywords.Thread |             // If you want context switch events you also need thread start events.  
                    KernelTraceEventParser.Keywords.ImageLoad |
                    KernelTraceEventParser.Keywords.Process,   /****** The second parameter indicates which kernel events should have stacks *****/
                    // KernelTraceEventParser.Keywords.ImageLoad |          // If you want Stacks image load (load library) events
                    // KernelTraceEventParser.Keywords.Profile |            // If you want Stacks for CPU sampling events 
                    // KernelTraceEventParser.Keywords.ContextSwitch |      // If you want Stacks for context switch events
                    KernelTraceEventParser.Keywords.None
                    );

                Out.WriteLine("Enabling CLR Exception and Load events (and stack for those events)");
                // We are monitoring exception events (with stacks) and module load events (with stacks)
                session.EnableProvider(
                    ClrTraceEventParser.ProviderGuid,
                    TraceEventLevel.Informational,
                    (ulong)(ClrTraceEventParser.Keywords.Jit |              // Turning on JIT events is necessary to resolve JIT compiled code 
                    ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | // This is needed if you want line number information in the stacks
                    ClrTraceEventParser.Keywords.Loader |                   // You must include loader events as well to resolve JIT compiled code. 
                    ClrTraceEventParser.Keywords.Exception |                // We want to see the exception events.   
                    ClrTraceEventParser.Keywords.Stack));                   // And stacks on all CLR events where it makes sense.  

                // The CLR events turned on above will let you resolve JIT compiled code as long as the JIT compilation
                // happens AFTER the session has started.   To handle the case for JIT compiled code that was already
                // compiled we need to tell the CLR to dump 'Rundown' events for all existing JIT compiled code.  We
                // do that here.  
                Out.WriteLine("Enabling CLR Events to 'catch up' on JIT compiled code in running processes.");
                session.EnableProvider(ClrRundownTraceEventParser.ProviderGuid, TraceEventLevel.Informational,
                    (ulong)(ClrTraceEventParser.Keywords.Jit |          // We need JIT events to be rundown to resolve method names
                    ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | // This is needed if you want line number information in the stacks
                    ClrTraceEventParser.Keywords.Loader |               // As well as the module load events.  
                    ClrTraceEventParser.Keywords.StartEnumeration));    // This indicates to do the rundown now (at enable time)

                // Because we care about symbols in native code or NGEN images, we need a SymbolReader to decode them.  

                // There is a lot of messages associated with looking up symbols, but we don't want to clutter up 
                // The output by default, so we save it to an internal buffer you can ToString in debug code.  
                // A real app should make this available somehow to the user, because sooner or later you DO need it.  
                TextWriter SymbolLookupMessages = new StringWriter();
                // TextWriter SymbolLookupMessages = Out;           // If you want the symbol debug spew to go to the output, use this. 

                // By default a symbol Reader uses whatever is in the _NT_SYMBOL_PATH variable.  However you can override
                // if you wish by passing it to the SymbolReader constructor.  Since we want this to work even if you 
                // have not set an _NT_SYMBOL_PATH, so we add the Microsoft default symbol server path to be sure/
                var symbolPath = new SymbolPath(SymbolPath.SymbolPathFromEnvironment).Add(SymbolPath.MicrosoftSymbolServerPath);
                SymbolReader symbolReader = new SymbolReader(SymbolLookupMessages, symbolPath.ToString());

                Out.WriteLine("Open a real time TraceLog session (which understands how to decode stacks).");
                using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session)) 
                {
                    // We use this action in the particular callbacks below.  Basically we pass in a symbol reader so we can decode the stack.  
                    // Often the symbol reader is a global variable instead.  
                    Action<TraceEvent> PrintEvent = ((TraceEvent data) => Print(data, symbolReader));

                    // We will print Exceptions and ModuleLoad events. (with stacks).  
                    traceLogSource.Clr.ExceptionStart += PrintEvent;
                    traceLogSource.Clr.LoaderModuleLoad += PrintEvent;
                    // traceLogSource.Clr.All += PrintEvent;

                    // If you want to see stacks for various other kernel events, uncomment these (you also need to turn on the events above)
                    traceLogSource.Kernel.PerfInfoSample += ((SampledProfileTraceData data) => Print(data, symbolReader));
                    // traceLogSource.Kernel.ImageLoad += ((ImageLoadTraceData data) => Print(data, symbolReader));

                    // process events until Ctrl-C is pressed or timeout expires
                    Out.WriteLine("Waiting {0} sec for Events.  Run managed code to see data. ", monitoringTimeSec);
                    Out.WriteLine("Keep in mind there is a several second buffering delay");

                    // Set up a timer to stop processing after monitoringTimeSec 
                    timer = new Timer(delegate(object state)
                    {
                        Out.WriteLine("Stopped Monitoring after {0} sec", monitoringTimeSec);
                        if (session != null)
                            session.Dispose();
                        session = null;
                    }, null, monitoringTimeSec * 1000, Timeout.Infinite);

                    traceLogSource.Process();
                }
            }
            Out.WriteLine("Finished");
            if (timer != null)
                timer.Dispose();    // Turn off the timer.  
        }