Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
        }