public ISymbolReader LoadPdbForModule(ModuleDefinition module) { using (Tracer t = new Tracer(myType, "LoadPdbForModule")) { string fileName = module.Assembly.MainModule.FullyQualifiedName; t.Info("Module file name: {0}", fileName); ISymbolReader reader = null; if (!this.myFile2PdbMap.TryGetValue(fileName, out reader)) { if (this.myFailedPdbs.Contains(fileName)) { t.Warning("This pdb could not be successfully downloaded"); return reader; } for (int i = 0; i < 2; i++) { try { reader = this.myPdbFactory.GetSymbolReader(module, fileName); this.myFile2PdbMap[fileName] = reader; break; } catch (Exception ex) { t.Error(Level.L3, ex, "Pdb did not match or it is not present"); string pdbFileName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb"); try { File.Delete(pdbFileName); } catch (Exception delex) { t.Error(Level.L2, delex, "Could not delete pdb {0}", pdbFileName); } // When we have symbol server we try to make us of it for matches. if (String.IsNullOrEmpty(this.mySymbolServer)) { break; } t.Info("Try to download pdb from symbol server {0}", this.mySymbolServer); bool bDownloaded = this.myDownLoader.DownloadPdbs(new FileQuery(fileName), this.mySymbolServer); t.Info("Did download pdb {0} from symbol server with return code: {1}", fileName, bDownloaded); if (bDownloaded == false || i == 1) // second try did not work out as well { this.myFailedPdbs.Add(fileName); break; } } } } return reader; } }
private void DeleteOldPdb(string binaryName) { using (var t = new Tracer(Level.L5, myType, "DeleteOldPdb")) { var pdbFile = GetPdbNameFromBinaryName(binaryName); t.Info("Try to delete pdb {0} for binary {1}", pdbFile, binaryName); try { File.Delete(pdbFile); } catch (FileNotFoundException ex) { t.Error(ex, "No old pdb file did exist"); } catch (Exception ex) { t.Error(ex, "Could not delete old pdb file"); } } }
public static AssemblyDefinition LoadCecilAssembly(string fileName, bool immediateLoad = false, bool? readSymbols = null) { using (var t = new Tracer(Level.L5, myType, "LoadCecilAssembly")) { var pdbPath = Path.ChangeExtension(fileName, "pdb"); var tryReadSymbols = readSymbols ?? File.Exists(pdbPath); var fileInfo = new FileInfo(fileName); if (fileInfo.Length == 0) { t.Info("File {0} has zero byte length", fileName); return null; } try { var readingMode = immediateLoad ? ReadingMode.Immediate : ReadingMode.Deferred; var assemblyResolver = new DefaultAssemblyResolver(); assemblyResolver.AddSearchDirectory(fileInfo.Directory.FullName); var readerParameters = new ReaderParameters { ReadSymbols = tryReadSymbols, ReadingMode = readingMode, AssemblyResolver = assemblyResolver }; var assemblyDef = AssemblyDefinition.ReadAssembly(fileName, readerParameters); // Managed C++ assemblies are not supported by Mono Cecil if (IsManagedCppAssembly(assemblyDef)) { t.Info("File {0} is a managed C++ assembly", fileName); return null; } return assemblyDef; } catch (BadImageFormatException) // Ignore invalid images { } catch (IndexOutOfRangeException) { t.Info("File {0} is a managed C++ assembly", fileName); } catch (NullReferenceException) // ignore managed c++ targets { t.Info("File {0} is a managed C++ assembly", fileName); } catch (ArgumentOutOfRangeException) { t.Info("File {0} is a managed C++ assembly", fileName); } catch (Exception ex) { t.Error(Level.L1, "Could not read assembly {0}: {1}", fileName, ex); } return null; } }
/// <summary> /// Downloads the pdbs from the symbol server. /// </summary> /// <param name="query">The query.</param> /// <param name="symbolServer">The symbol server name.</param> /// <param name="downloadDir">The download directory. Can be null.</param> /// <returns> /// true if all symbols could be downloaded. False otherwise. /// </returns> public bool DownloadPdbs(FileQuery query, string symbolServer, string downloadDir) { using (var t = new Tracer(myType, "DownloadPdbs")) { var lret = SymChkExecutor.bCanStartSymChk; var currentFailCount = this.FailedPdbs.Count; var fileQueue = query.EnumerateFiles; var aggregator = new BlockingQueueAggregator<string>(fileQueue); Action<string> downLoadPdbThread = (string fileName) => { var pdbFileName = GetPdbNameFromBinaryName(fileName); // delete old pdb to ensure that the new matching pdb is really downloaded. Symchk does not replace existing but not matching pdbs. try { File.Delete(pdbFileName); } catch { } if (!this.Executor.DownLoadPdb(fileName, symbolServer, downloadDir)) { lock (this.FailedPdbs) { this.FailedPdbs.Add(Path.GetFileName(fileName)); } } else { lock (this.FailedPdbs) { this.SucceededPdbCount++; } } }; var dispatcher = new WorkItemDispatcher<string>(this.myDownLoadThreadCount, downLoadPdbThread, "Pdb Downloader", aggregator, WorkItemOptions.AggregateExceptions); try { dispatcher.Dispose(); } catch (AggregateException ex) { t.Error(ex, "Got error during pdb download"); lret = false; } if (this.FailedPdbs.Count > currentFailCount) { t.Warning("The failed pdb count has increased by {0}", this.FailedPdbs.Count - currentFailCount); lret = false; } return lret; } }