Esempio n. 1
0
        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));
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
 public override string TryDownloadPdb(ISymbolNotification notification)
 {
     throw new NotImplementedException();
 }
Esempio n. 4
0
        /// <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;
        }
Esempio n. 5
0
        /// <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();
            }
        }
Esempio n. 6
0
        /// <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;
        }
Esempio n. 7
0
        /// <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;
        }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
 public override string TryDownloadPdb(ISymbolNotification notification)
 {
     return null;
 }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
 public override string TryDownloadPdb(ISymbolNotification notification)
 {
     throw new NotImplementedException();
 }
Esempio n. 12
0
 public override string TryDownloadPdb(ISymbolNotification notification)
 {
     return(null);
 }
Esempio n. 13
0
        public string TryDownloadDac(ISymbolNotification notification)
        {
            if (_dacLocation != null)
                return _dacLocation;

            SymbolLocator locator = _dataTarget.SymbolLocator;
            return locator.FindBinary(DacInfo, false);
        }
Esempio n. 14
0
 public virtual string TryDownloadPdb(ISymbolNotification notification) { return TryDownloadPdb(); }