/// <summary> /// This 'cleans up' a symbol path. In particular /// Empty ones are replaced with good defaults (symweb or msdl) /// All symbol server specs have local caches (%Temp%\symbols if nothing else is specified). /// /// Note that this routine does NOT update _NT_SYMBOL_PATH. /// </summary> public static SymPath CleanSymbolPath() { string symPathStr = _NT_SYMBOL_PATH; if (symPathStr.Length == 0) symPathStr = MicrosoftSymbolServerPath; var symPath = new SymPath(symPathStr); return symPath.InsureHasCache(symPath.DefaultSymbolCache).CacheFirst(); }
/// <summary> /// Removes all references to remote paths. This insures that network issues don't cause grief. /// </summary> public SymPath LocalOnly() { var ret = new SymPath(); foreach (var elem in Elements) { ret.Add(elem.LocalOnly()); } return(ret); }
/// <summary> /// People can use symbol servers without a local cache. This is bad, add one if necessary. /// </summary> public SymPath InsureHasCache(string defaultCachePath) { var ret = new SymPath(); foreach (var elem in Elements) { ret.Add(elem.InsureHasCache(defaultCachePath)); } return(ret); }
/// <summary> /// This 'cleans up' a symbol path. In particular /// Empty ones are replaced with good defaults (symweb or msdl) /// All symbol server specs have local caches (%Temp%\symbols if nothing else is specified). /// /// Note that this routine does NOT update _NT_SYMBOL_PATH. /// </summary> public static SymPath CleanSymbolPath() { string symPathStr = _NT_SYMBOL_PATH; if (symPathStr.Length == 0) { symPathStr = MicrosoftSymbolServerPath; } var symPath = new SymPath(symPathStr); return(symPath.InsureHasCache(symPath.DefaultSymbolCache).CacheFirst()); }
/// <summary> /// Opens a new SymbolReader. All diagnostics messages about symbol lookup go to 'log'. /// </summary> public SymbolReader(TextWriter log, SymPath nt_symbol_path) { SymbolPath = nt_symbol_path; log.WriteLine("Created SymbolReader with SymbolPath {0}", nt_symbol_path); // TODO FIX NOW. the code below does not support probing a file extension directory. // we work around this by adding more things to the symbol path var newSymPath = new SymPath(); foreach (var symElem in SymbolPath.Elements) { newSymPath.Add(symElem); if (!symElem.IsSymServer) { var probe = Path.Combine(symElem.Target, "dll"); if (Directory.Exists(probe)) newSymPath.Add(probe); probe = Path.Combine(symElem.Target, "exe"); if (Directory.Exists(probe)) newSymPath.Add(probe); } } var newSymPathStr = newSymPath.ToString(); // log.WriteLine("Morphed Symbol Path: {0}", newSymPathStr); this.m_log = log; SymbolReaderNativeMethods.SymOptions options = SymbolReaderNativeMethods.SymGetOptions(); SymbolReaderNativeMethods.SymSetOptions( SymbolReaderNativeMethods.SymOptions.SYMOPT_DEBUG | // SymbolReaderNativeMethods.SymOptions.SYMOPT_DEFERRED_LOADS | SymbolReaderNativeMethods.SymOptions.SYMOPT_LOAD_LINES | SymbolReaderNativeMethods.SymOptions.SYMOPT_EXACT_SYMBOLS | SymbolReaderNativeMethods.SymOptions.SYMOPT_UNDNAME ); m_currentProcess = Process.GetCurrentProcess(); // Only here to insure processHandle does not die. TODO get on safeHandles. m_currentProcessHandle = m_currentProcess.Handle; bool success = SymbolReaderNativeMethods.SymInitializeW(m_currentProcessHandle, newSymPathStr, false); if (!success) { // This captures the GetLastEvent (and has to happen before calling CloseHandle() m_currentProcessHandle = IntPtr.Zero; throw new Win32Exception(); } m_callback = new SymbolReaderNativeMethods.SymRegisterCallbackProc(this.StatusCallback); success = SymbolReaderNativeMethods.SymRegisterCallbackW64(m_currentProcessHandle, m_callback, 0); Debug.Assert(success); }
public DataTargetImpl(IDataReader dataReader, IDebugClient client) { if (dataReader == null) throw new ArgumentNullException("dataReader"); m_dataReader = dataReader; m_client = client; m_architecture = m_dataReader.GetArchitecture(); var sympath = SymPath._NT_SYMBOL_PATH; if (string.IsNullOrEmpty(sympath)) sympath = SymPath.MicrosoftSymbolServerPath; m_symPath = new SymPath(sympath); }
/// <summary> /// Create a new symbol path which first search all machine local locations (either explicit location or symbol server cache locations) /// folloed by all non-local symbol server. This produces better behavior (If you can find it locally it will be fast) /// </summary> public SymPath CacheFirst() { var ret = new SymPath(); foreach (var elem in Elements) { if (elem.IsSymServer && elem.IsRemote) { continue; } ret.Add(elem); } foreach (var elem in Elements) { if (elem.IsSymServer && elem.IsRemote) { ret.Add(elem); } } return(ret); }
/// <summary> /// Opens a new SymbolReader. All diagnostics messages about symbol lookup go to 'log'. /// </summary> public SymbolReader(TextWriter log, SymPath nt_symbol_path) { SymbolPath = nt_symbol_path; log.WriteLine("Created SymbolReader with SymbolPath {0}", nt_symbol_path); // TODO FIX NOW. the code below does not support probing a file extension directory. // we work around this by adding more things to the symbol path var newSymPath = new SymPath(); foreach (var symElem in SymbolPath.Elements) { newSymPath.Add(symElem); if (!symElem.IsSymServer) { var probe = Path.Combine(symElem.Target, "dll"); if (Directory.Exists(probe)) newSymPath.Add(probe); probe = Path.Combine(symElem.Target, "exe"); if (Directory.Exists(probe)) newSymPath.Add(probe); } } var newSymPathStr = newSymPath.ToString(); // log.WriteLine("Morphed Symbol Path: {0}", newSymPathStr); this._log = log; SymbolReaderNativeMethods.SymOptions options = SymbolReaderNativeMethods.SymGetOptions(); SymbolReaderNativeMethods.SymSetOptions( SymbolReaderNativeMethods.SymOptions.SYMOPT_DEBUG | // SymbolReaderNativeMethods.SymOptions.SYMOPT_DEFERRED_LOADS | SymbolReaderNativeMethods.SymOptions.SYMOPT_LOAD_LINES | SymbolReaderNativeMethods.SymOptions.SYMOPT_EXACT_SYMBOLS | SymbolReaderNativeMethods.SymOptions.SYMOPT_UNDNAME ); if (newSymPathStr != s_symPath) StaticInit(newSymPathStr); }
// TODO FIX NOW review and use instead of FindSymbolFilePath public string FindSymbolFilePath2(string pdbSimpleName, Guid pdbIndexGuid, int pdbIndexAge, string dllFilePath = null, string fileVersion = "") { string pdbPath = null; string pdbIndexPath = null; SymPath path = new SymPath(this.SymbolPath); foreach (SymPathElement element in path.Elements) { if (element.IsSymServer) { if (pdbIndexPath == null) pdbIndexPath = pdbSimpleName + @"\" + pdbIndexGuid.ToString("N") + pdbIndexAge.ToString() + @"\" + pdbSimpleName; string cache = element.Cache; if (cache == null) cache = path.DefaultSymbolCache; pdbPath = GetFileFromServer(element.Target, pdbIndexPath, cache); } else { string filePath = Path.Combine(element.Target, pdbSimpleName); if (File.Exists(filePath)) { SymbolModule module = this.OpenSymbolFile(filePath); if ((module.PdbGuid == pdbIndexGuid) && (module.PdbAge == pdbIndexAge)) pdbPath = filePath; } } } if (pdbPath != null) this.m_log.WriteLine("Successfully found PDB {0}\r\n GUID {1} Age {2} Version {3}", new object[] { pdbSimpleName, pdbIndexGuid, pdbIndexAge, fileVersion }); return this.CacheFileLocally(pdbPath, pdbIndexGuid, pdbIndexAge); }
/// <summary> /// Create a new symbol path which first search all machine local locations (either explicit location or symbol server cache locations) /// folloed by all non-local symbol server. This produces better behavior (If you can find it locally it will be fast) /// </summary> public SymPath CacheFirst() { var ret = new SymPath(); foreach (var elem in Elements) { if (elem.IsSymServer && elem.IsRemote) continue; ret.Add(elem); } foreach (var elem in Elements) { if (elem.IsSymServer && elem.IsRemote) ret.Add(elem); } return ret; }
/// <summary> /// Removes all references to remote paths. This insures that network issues don't cause grief. /// </summary> public SymPath LocalOnly() { var ret = new SymPath(); foreach (var elem in Elements) ret.Add(elem.LocalOnly()); return ret; }
/// <summary> /// People can use symbol servers without a local cache. This is bad, add one if necessary. /// </summary> public SymPath InsureHasCache(string defaultCachePath) { var ret = new SymPath(); foreach (var elem in Elements) ret.Add(elem.InsureHasCache(defaultCachePath)); return ret; }