diff --git a/src/TraceEvent/Computers/SampleProfilerThreadTimeComputer.cs b/src/TraceEvent/Computers/SampleProfilerThreadTimeComputer.cs index 045c97243..1ee6d6da7 100644 --- a/src/TraceEvent/Computers/SampleProfilerThreadTimeComputer.cs +++ b/src/TraceEvent/Computers/SampleProfilerThreadTimeComputer.cs @@ -41,6 +41,13 @@ public SampleProfilerThreadTimeComputer(TraceLog eventLog, SymbolReader symbolRe /// If set we compute thread time using Tasks /// public bool UseTasks; + + /// + /// Track additional info on like EventName or so. + /// Default to true to keep backward compatibility. + /// + public bool TrackAdditionalInfo = true; + /// /// Use start-stop activities as the grouping construct. /// @@ -202,17 +209,20 @@ public void GenerateThreadTimeStacks(MutableTraceEventStackSource outputStackSou StackSourceCallStackIndex stackIndex = GetCallStack(data, thread); - // Tack on additional info about the event. - var fieldNames = data.PayloadNames; - for (int i = 0; i < fieldNames.Length; i++) + // Tack on additional info about the event. + if (TrackAdditionalInfo) { - var fieldName = fieldNames[i]; - var value = data.PayloadString(i); - var fieldNodeName = "EventData: " + fieldName + "=" + value; - var fieldNodeIndex = m_outputStackSource.Interner.FrameIntern(fieldNodeName); - stackIndex = m_outputStackSource.Interner.CallStackIntern(fieldNodeIndex, stackIndex); + var fieldNames = data.PayloadNames; + for (int i = 0; i < fieldNames.Length; i++) + { + var fieldName = fieldNames[i]; + var value = data.PayloadString(i); + var fieldNodeName = "EventData: " + fieldName + "=" + value; + var fieldNodeIndex = m_outputStackSource.Interner.FrameIntern(fieldNodeName); + stackIndex = m_outputStackSource.Interner.CallStackIntern(fieldNodeIndex, stackIndex); + } + stackIndex = m_outputStackSource.Interner.CallStackIntern(m_outputStackSource.Interner.FrameIntern("EventName: " + data.ProviderName + "/" + data.EventName), stackIndex); } - stackIndex = m_outputStackSource.Interner.CallStackIntern(m_outputStackSource.Interner.FrameIntern("EventName: " + data.ProviderName + "/" + data.EventName), stackIndex); m_threadState[(int)thread.ThreadIndex].LogThreadStack(data.TimeStampRelativeMSec, stackIndex, thread, this, false); }; diff --git a/src/TraceEvent/Computers/ThreadTimeComputer.cs b/src/TraceEvent/Computers/ThreadTimeComputer.cs index 2370a2084..c958f764a 100644 --- a/src/TraceEvent/Computers/ThreadTimeComputer.cs +++ b/src/TraceEvent/Computers/ThreadTimeComputer.cs @@ -55,6 +55,11 @@ public ThreadTimeStackComputer(TraceLog eventLog, SymbolReader symbolReader) /// public bool UseTasks; /// + /// Track additional info on like EventName or so. + /// Default to true to keep backward compatibility. + /// + public bool TrackAdditionalInfo = true; + /// /// If set we compute blocked time /// [Obsolete("Use Thread Time instead")] @@ -296,17 +301,20 @@ public void GenerateThreadTimeStacks(MutableTraceEventStackSource outputStackSou StackSourceCallStackIndex stackIndex = GetCallStack(data, thread); - // Tack on additional info about the event. - var fieldNames = data.PayloadNames; - for (int i = 0; i < fieldNames.Length; i++) + // Tack on additional info about the event. + if (TrackAdditionalInfo) { - var fieldName = fieldNames[i]; - var value = data.PayloadString(i); - var fieldNodeName = "EventData: " + fieldName + "=" + value; - var fieldNodeIndex = m_outputStackSource.Interner.FrameIntern(fieldNodeName); - stackIndex = m_outputStackSource.Interner.CallStackIntern(fieldNodeIndex, stackIndex); + var fieldNames = data.PayloadNames; + for (int i = 0; i < fieldNames.Length; i++) + { + var fieldName = fieldNames[i]; + var value = data.PayloadString(i); + var fieldNodeName = "EventData: " + fieldName + "=" + value; + var fieldNodeIndex = m_outputStackSource.Interner.FrameIntern(fieldNodeName); + stackIndex = m_outputStackSource.Interner.CallStackIntern(fieldNodeIndex, stackIndex); + } + stackIndex = m_outputStackSource.Interner.CallStackIntern(m_outputStackSource.Interner.FrameIntern("EventName: " + data.ProviderName + "/" + data.EventName), stackIndex); } - stackIndex = m_outputStackSource.Interner.CallStackIntern(m_outputStackSource.Interner.FrameIntern("EventName: " + data.ProviderName + "/" + data.EventName), stackIndex); m_threadState[(int)thread.ThreadIndex].LogCPUStack(data.TimeStampRelativeMSec, stackIndex, thread, this, false); }; diff --git a/src/TraceEvent/Symbols/NativeSymbolModule.cs b/src/TraceEvent/Symbols/NativeSymbolModule.cs index 2c007e514..e41d35259 100644 --- a/src/TraceEvent/Symbols/NativeSymbolModule.cs +++ b/src/TraceEvent/Symbols/NativeSymbolModule.cs @@ -107,32 +107,35 @@ public string FindNameForRva(uint rva, ref uint symbolStartRva) ret = ret.Substring(0, dollarIdx); // See if we have a Project N map that maps $_NN to a pre-merged assembly name - var mergedAssembliesMap = GetMergedAssembliesMap(); - if (mergedAssembliesMap != null) + if (LookupAssemblyNameForCompiledNative) { - bool prefixMatchFound = false; - Regex prefixMatch = new Regex(@"\$(\d+)_"); - ret = prefixMatch.Replace(ret, delegate (Match m) + var mergedAssembliesMap = GetMergedAssembliesMap(); + if (mergedAssembliesMap != null) { - prefixMatchFound = true; - var original = m.Groups[1].Value; - var moduleIndex = int.Parse(original); - string fullAssemblyName; - if (mergedAssembliesMap.TryGetValue(moduleIndex, out fullAssemblyName)) + bool prefixMatchFound = false; + Regex prefixMatch = new Regex(@"\$(\d+)_"); + ret = prefixMatch.Replace(ret, delegate (Match m) { - try + prefixMatchFound = true; + var original = m.Groups[1].Value; + var moduleIndex = int.Parse(original); + string fullAssemblyName; + if (mergedAssembliesMap.TryGetValue(moduleIndex, out fullAssemblyName)) { - var assemblyName = new AssemblyName(fullAssemblyName); - return assemblyName.Name + "!"; + try + { + var assemblyName = new AssemblyName(fullAssemblyName); + return assemblyName.Name + "!"; + } + catch (Exception) { } // Catch all AssemlyName fails with ' in the name. } - catch (Exception) { } // Catch all AssemlyName fails with ' in the name. - } - return original; - }); + return original; + }); - // corefx.dll does not have a tag. TODO this feels like a hack! - if (!prefixMatchFound) - ret = "mscorlib!" + ret; + // corefx.dll does not have a tag. TODO this feels like a hack! + if (!prefixMatchFound) + ret = "mscorlib!" + ret; + } } return ret; } @@ -948,6 +951,13 @@ internal ManagedSymbolModule PdbForSourceServer } } + /// + /// Decide if we try to get a Project N map that maps $_NN to a pre-merged assembly name. + /// This is an exprimental code. Default to true because we don't have this switch when the + /// code is initially introduced. Deprecate this when the code is mature enough. + /// + internal bool LookupAssemblyNameForCompiledNative { get; set; } = true; + /// /// For Project N modules it returns the list of pre merged IL assemblies and the corresponding mapping. /// diff --git a/src/TraceEvent/Symbols/SymbolReader.cs b/src/TraceEvent/Symbols/SymbolReader.cs index 3333ef064..442eeff13 100644 --- a/src/TraceEvent/Symbols/SymbolReader.cs +++ b/src/TraceEvent/Symbols/SymbolReader.cs @@ -301,7 +301,7 @@ public ManagedSymbolModule OpenSymbolFile(string pdbFilePath) else { stream.Dispose(); - ret = new NativeSymbolModule(this, pdbFilePath); + ret = new NativeSymbolModule(this, pdbFilePath) { LookupAssemblyNameForCompiledNative = this.LookupAssemblyNameForCompiledNative }; } m_symbolModuleCache.Add(pdbFilePath, ret); } @@ -403,6 +403,12 @@ public string SourceCacheDirectory /// public TextWriter Log { get { return m_log; } } + /// + /// Sets whether try to look for assembly name for compiled to native assemblies. + /// Default to because the code was introduced without this flag. + /// + public bool LookupAssemblyNameForCompiledNative { get; set; } = true; + /// /// Given a full filename path to an NGEN image, insure that there is an NGEN image for it /// in the symbol cache. If one already exists, this method simply returns that. If not @@ -1382,7 +1388,7 @@ struct PdbSignature : IEquatable private Cache m_pdbPathCache; private string m_symbolPath; -#endregion + #endregion } /// @@ -1430,7 +1436,7 @@ public abstract class ManagedSymbolModule /// protected virtual string GetSourceLinkJson() { return null; } -#region private + #region private protected ManagedSymbolModule(SymbolReader reader, string path) { _pdbPath = path; _reader = reader; } @@ -1513,7 +1519,7 @@ private List> ParseSourceLinkJson(string sourceLinkJson) SymbolReader _reader; List> _sourceLinkMapping; // Used by SourceLink to map build paths to URLs (see GetUrlForFilePath) bool _sourceLinkMappingInited; // Lazy init flag. -#endregion + #endregion } /// @@ -1530,7 +1536,7 @@ public class SourceLocation /// public int LineNumber { get; private set; } -#region private + #region private internal SourceLocation(SourceFile sourceFile, int lineNumber) { // The library seems to see FEEFEE for the 'unknown' line number. 0 seems more intuitive @@ -1540,7 +1546,7 @@ internal SourceLocation(SourceFile sourceFile, int lineNumber) SourceFile = sourceFile; LineNumber = lineNumber; } -#endregion + #endregion } /// @@ -1662,7 +1668,7 @@ public virtual string GetSourceFile(bool requireChecksumMatch = false) /// ; public bool ChecksumMatches { get { return _checksumMatches; } } -#region private + #region private protected SourceFile(ManagedSymbolModule symbolModule) { _symbolModule = symbolModule; } protected TextWriter _log { get { return _symbolModule._log; } } @@ -1783,7 +1789,7 @@ private static bool ArrayEquals(byte[] bytes1, byte[] bytes2) protected string _filePath; bool _getSourceCalled; bool _checksumMatches; -#endregion + #endregion } }