public virtual async Task <bool> LoadSymbolsAsync( SbModule lldbModule, TextWriter searchLog, bool useSymbolStores) { if (lldbModule == null) { throw new ArgumentNullException(nameof(lldbModule)); } searchLog = searchLog ?? TextWriter.Null; // Return early if symbols are already loaded if (moduleUtil.HasSymbolsLoaded(lldbModule)) { return(true); } var(symbolFileDir, symbolFileName) = await GetSymbolFileDirAndNameAsync(lldbModule, searchLog); if (string.IsNullOrEmpty(symbolFileName)) { await searchLog.WriteLineAsync(ErrorStrings.SymbolFileNameUnknown); Trace.WriteLine(ErrorStrings.SymbolFileNameUnknown); return(false); } BuildId uuid = new BuildId(lldbModule.GetUUIDString()); // If we have a search directory, let us look up the symbol file in there. if (!string.IsNullOrEmpty(symbolFileDir)) { string symbolFilePath = string.Empty; try { symbolFilePath = Path.Combine(symbolFileDir, symbolFileName); BuildId fileUUID = await binaryFileUtil.ReadBuildIdAsync(symbolFilePath); if (fileUUID == uuid) { return(AddSymbolFile(symbolFilePath, lldbModule, searchLog)); } } catch (Exception e) when(e is InvalidBuildIdException || e is BinaryFileUtilException || e is ArgumentException) { // Just ignore the symbol file path if we could not read the build Id. Trace.WriteLine($"Could not read build Id from {symbolFilePath} " + $"for module {lldbModule.GetFileSpec().GetFilename()} " + $"(Message: {e.Message})."); } } var filepath = useSymbolStores ? await moduleFileFinder.FindFileAsync( symbolFileName, uuid, true, searchLog) : null; if (filepath == null) { return(false); } return(AddSymbolFile(filepath, lldbModule, searchLog)); }
async Task <(string, string)> GetSymbolFileDirAndNameAsync( SbModule lldbModule, TextWriter log) { var symbolFileSpec = lldbModule.GetSymbolFileSpec(); var symbolFileDirectory = symbolFileSpec?.GetDirectory(); var symbolFileName = symbolFileSpec?.GetFilename(); var binaryFileSpec = lldbModule.GetFileSpec(); var binaryDirectory = binaryFileSpec?.GetDirectory(); var binaryFilename = binaryFileSpec?.GetFilename(); // If there is no path to the binary, there is nothing we can do. if (string.IsNullOrEmpty(binaryDirectory) || string.IsNullOrEmpty(binaryFilename)) { return(symbolFileDirectory, symbolFileName); } // When lldb can't find the symbol file, it sets the symbol file spec to the path of // the binary file. If the file name or path is different, we just return the filename // (if it is not empty). if (!string.IsNullOrEmpty(symbolFileName) && (symbolFileDirectory != binaryDirectory || symbolFileName != binaryFilename)) { return(symbolFileDirectory, symbolFileName); } symbolFileDirectory = null; symbolFileName = null; // Let us look up the symbol file name and directory in the binary. string binaryPath; try { binaryPath = Path.Combine(binaryDirectory, binaryFilename); } catch (ArgumentException e) { var errorString = ErrorStrings.InvalidBinaryPathOrName(binaryDirectory, binaryFilename, e.Message); Trace.WriteLine(errorString); await log.WriteLineAsync(errorString); return(null, null); } // Read the symbol file name from the binary. try { symbolFileName = await binaryFileUtil.ReadSymbolFileNameAsync(binaryPath); } catch (BinaryFileUtilException e) { Trace.WriteLine(e.ToString()); await log.WriteLineAsync(e.Message); return(null, null); } // Try to read the debug info directory. try { symbolFileDirectory = await binaryFileUtil.ReadSymbolFileDirAsync(binaryPath); } catch (BinaryFileUtilException e) { // Just log the message (the directory section is optional). Trace.WriteLine(e.Message); await log.WriteLineAsync(e.Message); } return(symbolFileDirectory, symbolFileName); }