|
9 | 9 | #include "SymbolLocatorDebuginfod.h"
|
10 | 10 |
|
11 | 11 | #include "lldb/Core/PluginManager.h"
|
| 12 | +#include "lldb/Interpreter/OptionValueString.h" |
12 | 13 | #include "lldb/Utility/Args.h"
|
| 14 | +#include "lldb/Utility/LLDBLog.h" |
| 15 | +#include "lldb/Utility/Log.h" |
13 | 16 |
|
14 | 17 | #include "llvm/Debuginfod/Debuginfod.h"
|
15 | 18 | #include "llvm/Debuginfod/HTTPClient.h"
|
@@ -54,6 +57,32 @@ class PluginProperties : public Properties {
|
54 | 57 | return urls;
|
55 | 58 | }
|
56 | 59 |
|
| 60 | + llvm::Expected<std::string> GetCachePath() { |
| 61 | + OptionValueString *s = |
| 62 | + m_collection_sp->GetPropertyAtIndexAsOptionValueString( |
| 63 | + ePropertySymbolCachePath); |
| 64 | + // If we don't have a valid cache location, use the default one. |
| 65 | + if (!s || !s->GetCurrentValueAsRef().size()) { |
| 66 | + llvm::Expected<std::string> maybeCachePath = |
| 67 | + llvm::getDefaultDebuginfodCacheDirectory(); |
| 68 | + if (!maybeCachePath) |
| 69 | + return maybeCachePath; |
| 70 | + return *maybeCachePath; |
| 71 | + } |
| 72 | + return s->GetCurrentValue(); |
| 73 | + } |
| 74 | + |
| 75 | + std::chrono::milliseconds GetTimeout() const { |
| 76 | + std::optional<uint64_t> seconds = |
| 77 | + m_collection_sp->GetPropertyAtIndexAs<uint64_t>(ePropertyTimeout); |
| 78 | + if (seconds && *seconds != 0) { |
| 79 | + return std::chrono::duration_cast<std::chrono::milliseconds>( |
| 80 | + std::chrono::seconds(*seconds)); |
| 81 | + } else { |
| 82 | + return llvm::getDefaultDebuginfodTimeout(); |
| 83 | + } |
| 84 | + } |
| 85 | + |
57 | 86 | private:
|
58 | 87 | void ServerURLsChangedCallback() {
|
59 | 88 | m_server_urls = GetDebugInfoDURLs();
|
@@ -112,31 +141,51 @@ SymbolLocator *SymbolLocatorDebuginfod::CreateInstance() {
|
112 | 141 | return new SymbolLocatorDebuginfod();
|
113 | 142 | }
|
114 | 143 |
|
115 |
| -static std::optional<FileSpec> GetFileForModule( |
116 |
| - const ModuleSpec &module_spec, |
117 |
| - std::function<llvm::Expected<std::string>(llvm::object::BuildIDRef)> |
118 |
| - PullFromServer) { |
119 |
| - if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) |
120 |
| - return {}; |
| 144 | +static std::optional<FileSpec> |
| 145 | +GetFileForModule(const ModuleSpec &module_spec, |
| 146 | + std::function<std::string(llvm::object::BuildID)> UrlBuilder) { |
121 | 147 | const UUID &module_uuid = module_spec.GetUUID();
|
122 |
| - if (module_uuid.IsValid() && llvm::canUseDebuginfod()) { |
123 |
| - llvm::object::BuildID build_id(module_uuid.GetBytes()); |
124 |
| - llvm::Expected<std::string> result = PullFromServer(build_id); |
125 |
| - if (result) |
126 |
| - return FileSpec(*result); |
127 |
| - // An error here should be logged as a failure in the Debuginfod library, |
128 |
| - // so just consume it here |
129 |
| - consumeError(result.takeError()); |
130 |
| - } |
| 148 | + // Don't bother if we don't have a valid UUID, Debuginfod isn't available, |
| 149 | + // or if the 'symbols.enable-external-lookup' setting is false. |
| 150 | + if (!module_uuid.IsValid() || !llvm::canUseDebuginfod() || |
| 151 | + !ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) |
| 152 | + return {}; |
| 153 | + |
| 154 | + // Grab LLDB's Debuginfod overrides from the |
| 155 | + // plugin.symbol-locator.debuginfod.* settings. |
| 156 | + PluginProperties &plugin_props = GetGlobalPluginProperties(); |
| 157 | + llvm::Expected<std::string> cache_path_or_err = plugin_props.GetCachePath(); |
| 158 | + // A cache location is *required*. |
| 159 | + if (!cache_path_or_err) |
| 160 | + return {}; |
| 161 | + std::string cache_path = *cache_path_or_err; |
| 162 | + llvm::SmallVector<llvm::StringRef> debuginfod_urls = |
| 163 | + llvm::getDefaultDebuginfodUrls(); |
| 164 | + std::chrono::milliseconds timeout = plugin_props.GetTimeout(); |
| 165 | + |
| 166 | + // We're ready to ask the Debuginfod library to find our file. |
| 167 | + llvm::object::BuildID build_id(module_uuid.GetBytes()); |
| 168 | + std::string url_path = UrlBuilder(build_id); |
| 169 | + std::string cache_key = llvm::getDebuginfodCacheKey(url_path); |
| 170 | + llvm::Expected<std::string> result = llvm::getCachedOrDownloadArtifact( |
| 171 | + cache_key, url_path, cache_path, debuginfod_urls, timeout); |
| 172 | + if (result) |
| 173 | + return FileSpec(*result); |
| 174 | + |
| 175 | + Log *log = GetLog(LLDBLog::Symbols); |
| 176 | + auto err_message = llvm::toString(result.takeError()); |
| 177 | + LLDB_LOGV(log, |
| 178 | + "Debuginfod failed to download symbol artifact {0} with error {1}", |
| 179 | + url_path, err_message); |
131 | 180 | return {};
|
132 | 181 | }
|
133 | 182 |
|
134 | 183 | std::optional<ModuleSpec> SymbolLocatorDebuginfod::LocateExecutableObjectFile(
|
135 | 184 | const ModuleSpec &module_spec) {
|
136 |
| - return GetFileForModule(module_spec, llvm::getCachedOrDownloadExecutable); |
| 185 | + return GetFileForModule(module_spec, llvm::getDebuginfodExecutableUrlPath); |
137 | 186 | }
|
138 | 187 |
|
139 | 188 | std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile(
|
140 | 189 | const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
|
141 |
| - return GetFileForModule(module_spec, llvm::getCachedOrDownloadDebuginfo); |
| 190 | + return GetFileForModule(module_spec, llvm::getDebuginfodDebuginfoUrlPath); |
142 | 191 | }
|
0 commit comments