public override string TryDownloadPdb(ISymbolNotification notification) { var dataTarget = m_runtime.DataTarget; if (notification == null) { notification = dataTarget.DefaultSymbolNotification ?? new NullSymbolNotification(); } if (m_peFile == null) { m_peFile = new PEFile(new ReadVirtualStream(m_runtime.DataReader, (long)m_imageBase, (long)m_size), true); } string pdbName; Guid pdbGuid; int rev; if (!m_peFile.GetPdbSignature(out pdbName, out pdbGuid, out rev)) { throw new ClrDiagnosticsException("Failed to get PDB signature from module.", ClrDiagnosticsException.HR.DataRequestError); } if (File.Exists(pdbName)) { return(pdbName); } var reader = dataTarget.SymbolReader; return(reader.FindSymbolFilePath(pdbName, pdbGuid, rev, notification)); }
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); }
public override string TryDownloadPdb(ISymbolNotification notification) { throw new NotImplementedException(); }
/// <summary> /// Looks up 'fileIndexPath' on the server 'urlForServer' copying the file to 'symbolCacheDir' and returning the /// path name there (thus it is always a local file). Unlike GetPhysicalFileFromServer, GetFileFromServer understands /// how to deal with compressed files and file.ptr (redirection). /// </summary> /// <returns>The path to a local file or null if the file cannot be found.</returns> private string GetFileFromServer(string urlForServer, string fileIndexPath, string symbolCacheDir, ISymbolNotification notification) { if (String.IsNullOrEmpty(urlForServer)) return null; // Just try to fetch the file directly var ret = GetPhysicalFileFromServer(urlForServer, fileIndexPath, symbolCacheDir, notification); if (ret != null) return ret; var targetPath = Path.Combine(symbolCacheDir, fileIndexPath); // See if it is a compressed file by replacing the last character of the name with an _ var compressedSigPath = fileIndexPath.Substring(0, fileIndexPath.Length - 1) + "_"; var compressedFilePath = GetPhysicalFileFromServer(urlForServer, compressedSigPath, symbolCacheDir, notification); if (compressedFilePath != null) { // Decompress it _log.WriteLine("Expanding {0} to {1}", compressedFilePath, targetPath); Command.Run("Expand " + Command.Quote(compressedFilePath) + " " + Command.Quote(targetPath)); File.Delete(compressedFilePath); notification.DecompressionComplete(targetPath); return targetPath; } // See if we have a file that tells us to redirect elsewhere. var filePtrSigPath = Path.Combine(Path.GetDirectoryName(fileIndexPath), "file.ptr"); var filePtrFilePath = GetPhysicalFileFromServer(urlForServer, filePtrSigPath, symbolCacheDir, notification); if (filePtrFilePath != null) { var filePtrData = File.ReadAllText(filePtrFilePath).Trim(); if (filePtrData.StartsWith("PATH:")) filePtrData = filePtrData.Substring(5); File.Delete(filePtrFilePath); // TODO FIX NOW can you use file.ptr to redirect to HTTP? if (!filePtrData.StartsWith("MSG:") && File.Exists(filePtrData)) { _log.WriteLine("Copying {0} to {1}", filePtrData, targetPath); // TODO FIX NOW don't use copyFile as it is not very interruptable, and this can take a while over a network. File.Copy(filePtrData, targetPath, true); return targetPath; } else _log.WriteLine("Error resolving file.Ptr: content '{0}'", filePtrData); } return null; }
/// <summary> /// This just copies a stream to a file path with logging. /// </summary> private void CopyStreamToFile(Stream fromStream, string fromUri, string fullDestPath, ISymbolNotification notification) { try { int total = 0; var dirName = Path.GetDirectoryName(fullDestPath); Directory.CreateDirectory(dirName); _log.WriteLine("Success Copying {0} to {1}", fromUri, fullDestPath); using (Stream toStream = File.Create(fullDestPath)) { byte[] buffer = new byte[8192]; int cnt = 0; for (;;) { int count = fromStream.Read(buffer, 0, buffer.Length); if (count == 0) break; toStream.Write(buffer, 0, count); total += count; notification.DownloadProgress(total); _log.Write("."); cnt++; if (cnt > 40) { _log.WriteLine(); _log.Flush(); cnt = 0; } System.Threading.Thread.Sleep(0); // allow interruption. } } notification.DownloadComplete(fullDestPath, fullDestPath[fullDestPath.Length - 1] == '_'); } finally { fromStream.Close(); _log.WriteLine(); } }
/// <summary> /// Fetches a file from the server 'serverPath' weith pdb signature path 'pdbSigPath' and places it in its /// correct location in 'symbolCacheDir' Will return the path of the cached copy if it succeeds, null otherwise. /// /// You should probably be using GetFileFromServer /// </summary> /// <param name="serverPath">path to server (eg. \\symbols\symbols or http://symweb) </param> /// <param name="pdbIndexPath">pdb path with signature (e.g clr.pdb/1E18F3E494DC464B943EA90F23E256432/clr.pdb)</param> /// <param name="symbolCacheDir">path to the symbol cache where files are fetched (e.g. %TEMP%\symbols) </param> /// <param name="notification">A callback to provide progress updates.</param> private string GetPhysicalFileFromServer(string serverPath, string pdbIndexPath, string symbolCacheDir, ISymbolNotification notification) { if (string.IsNullOrEmpty(serverPath)) return null; var fullDestPath = Path.Combine(symbolCacheDir, pdbIndexPath); if (!File.Exists(fullDestPath)) { if (serverPath.StartsWith("http:")) { var fullUri = serverPath + "/" + pdbIndexPath.Replace('\\', '/'); try { var req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(fullUri); req.UserAgent = "Microsoft-Symbol-Server/6.13.0009.1140"; var responce = req.GetResponse(); var fromStream = responce.GetResponseStream(); var dirName = Path.GetDirectoryName(fullDestPath); notification.FoundSymbolOnPath(fullUri); CopyStreamToFile(fromStream, fullUri, fullDestPath, notification); } catch (Exception e) { notification.ProbeFailed(fullUri); _log.WriteLine("Probe of {0} failed: {1}", fullUri, e.Message); return null; } } else { var fullSrcPath = Path.Combine(serverPath, pdbIndexPath); if (!File.Exists(fullSrcPath)) return null; Directory.CreateDirectory(Path.GetDirectoryName(fullDestPath)); File.Copy(fullSrcPath, fullDestPath); notification.FoundSymbolInCache(fullDestPath); } } else { notification.FoundSymbolInCache(fullDestPath); } return fullDestPath; }
/// <summary> /// This API looks up an executable file, by its build-timestamp and size (on a symbol server), 'fileName' should be /// a simple name (no directory), and you need the buildTimeStamp and sizeOfImage that are found in the PE header. /// /// Returns null if it cannot find anything. /// </summary> public string FindExecutableFilePath(string fileName, int buildTimeStamp, int sizeOfImage, ISymbolNotification notification) { Debug.Assert(notification != null); string exeIndexPath = null; foreach (SymPathElement element in SymbolPath.Elements) { if (element.IsSymServer) { if (exeIndexPath == null) exeIndexPath = fileName + @"\" + buildTimeStamp.ToString("x") + sizeOfImage.ToString("x") + @"\" + fileName; string cache = element.Cache; if (cache == null) cache = SymbolPath.DefaultSymbolCache; string targetPath = GetFileFromServer(element.Target, exeIndexPath, cache, notification); if (targetPath != null) return targetPath; } else { string filePath = Path.Combine(element.Target, fileName); _log.WriteLine("Probing file {0}", filePath); if (File.Exists(filePath)) { using (PEFile file = new PEFile(filePath)) { // TODO: This is incorrect. //if ((file.Header.TimeDateStampSec == buildTimeStamp) && (file.Header.SizeOfImage == sizeOfImage)) { notification.FoundSymbolOnPath(filePath); return filePath; } //m_log.WriteLine("Found file {0} but file timstamp:size {1}:{2} != desired {3}:{4}, rejecting.", // filePath, file.Header.TimeDateStampSec, file.Header.SizeOfImage, buildTimeStamp, sizeOfImage); } } notification.ProbeFailed(filePath); } } return null; }
public string FindSymbolFilePath(string pdbSimpleName, Guid pdbIndexGuid, int pdbIndexAge, ISymbolNotification notification) { string pdbIndexPath = null; foreach (SymPathElement element in SymbolPath.Elements) { if (element.IsSymServer) { pdbSimpleName = Path.GetFileName(pdbSimpleName); if (pdbIndexPath == null) pdbIndexPath = pdbSimpleName + @"\" + pdbIndexGuid.ToString().Replace("-", "") + pdbIndexAge.ToString("x") + @"\" + pdbSimpleName; string cache = element.Cache; if (cache == null) cache = SymbolPath.DefaultSymbolCache; string targetPath = GetFileFromServer(element.Target, pdbIndexPath, cache, notification); if (targetPath != null) return targetPath; } else { string filePath = Path.Combine(element.Target, pdbSimpleName); _log.WriteLine("Probing file {0}", filePath); if (File.Exists(filePath)) { using (PEFile file = new PEFile(filePath)) { IDiaDataSource source = DiaLoader.GetDiaSourceObject(); IDiaSession session; source.loadDataFromPdb(filePath); source.openSession(out session); if (pdbIndexGuid == session.globalScope.guid) { notification.FoundSymbolOnPath(filePath); return filePath; } _log.WriteLine("Found file {0} but guid {1} != desired {2}, rejecting.", filePath, session.globalScope.guid, pdbIndexGuid); } } notification.ProbeFailed(filePath); } } return null; }
public override string TryDownloadPdb(ISymbolNotification notification) { return null; }
public override string TryDownloadPdb(ISymbolNotification notification) { var dataTarget = m_runtime.DataTarget; if (notification == null) notification = dataTarget.DefaultSymbolNotification ?? new NullSymbolNotification(); if (m_peFile == null) m_peFile = new PEFile(new ReadVirtualStream(m_runtime.DataReader, (long)m_imageBase, (long)m_size), true); string pdbName; Guid pdbGuid; int rev; if (!m_peFile.GetPdbSignature(out pdbName, out pdbGuid, out rev)) throw new ClrDiagnosticsException("Failed to get PDB signature from module.", ClrDiagnosticsException.HR.DataRequestError); if (File.Exists(pdbName)) return pdbName; var reader = dataTarget.SymbolReader; return reader.FindSymbolFilePath(pdbName, pdbGuid, rev, notification); }
public override string TryDownloadPdb(ISymbolNotification notification) { return(null); }
public string TryDownloadDac(ISymbolNotification notification) { if (_dacLocation != null) return _dacLocation; SymbolLocator locator = _dataTarget.SymbolLocator; return locator.FindBinary(DacInfo, false); }
public virtual string TryDownloadPdb(ISymbolNotification notification) { return TryDownloadPdb(); }