Skip to content

Commit 6d5f8d3

Browse files
kevinfreiKevin Frei
andauthored
Added settings for DEBUGINFOD cache location and timeout (llvm#78605)
I've been working on more/better configuration for improving DEBUGINFOD support. This is the first (and easiest) slice of the work. I've added `timeout` and `cache-path` settings that can override the DEBUGINFOD library defaults (and environment variables.) I also renamed the `plugin.symbol-locator.debuginfod.server_urls` setting to `server-urls` to be more consistent with the rest of LLDB's settings (the underscore switch is switched to a hyphen) I've got a few tests that validate the cache-path setting (as a side-effect), but they've exposed a few bugs that I'll be putting up a separate PR for (which will include the tests). --------- Co-authored-by: Kevin Frei <[email protected]>
1 parent 7c53e9f commit 6d5f8d3

File tree

4 files changed

+113
-28
lines changed

4 files changed

+113
-28
lines changed

lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
#include "SymbolLocatorDebuginfod.h"
1010

1111
#include "lldb/Core/PluginManager.h"
12+
#include "lldb/Interpreter/OptionValueString.h"
1213
#include "lldb/Utility/Args.h"
14+
#include "lldb/Utility/LLDBLog.h"
15+
#include "lldb/Utility/Log.h"
1316

1417
#include "llvm/Debuginfod/Debuginfod.h"
1518
#include "llvm/Debuginfod/HTTPClient.h"
@@ -54,6 +57,32 @@ class PluginProperties : public Properties {
5457
return urls;
5558
}
5659

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+
5786
private:
5887
void ServerURLsChangedCallback() {
5988
m_server_urls = GetDebugInfoDURLs();
@@ -112,31 +141,51 @@ SymbolLocator *SymbolLocatorDebuginfod::CreateInstance() {
112141
return new SymbolLocatorDebuginfod();
113142
}
114143

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) {
121147
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);
131180
return {};
132181
}
133182

134183
std::optional<ModuleSpec> SymbolLocatorDebuginfod::LocateExecutableObjectFile(
135184
const ModuleSpec &module_spec) {
136-
return GetFileForModule(module_spec, llvm::getCachedOrDownloadExecutable);
185+
return GetFileForModule(module_spec, llvm::getDebuginfodExecutableUrlPath);
137186
}
138187

139188
std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile(
140189
const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
141-
return GetFileForModule(module_spec, llvm::getCachedOrDownloadDebuginfo);
190+
return GetFileForModule(module_spec, llvm::getDebuginfodDebuginfoUrlPath);
142191
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
include "../../../../include/lldb/Core/PropertiesBase.td"
22

33
let Definition = "symbollocatordebuginfod" in {
4-
def ServerURLs : Property<"server_urls", "Array">,
4+
def ServerURLs : Property<"server-urls", "Array">,
55
ElementType<"String">,
66
Desc<"An ordered list of Debuginfod server URLs to query for symbols. This defaults to the contents of the DEBUGINFOD_URLS environment variable.">;
7+
def SymbolCachePath: Property<"cache-path", "String">,
8+
DefaultStringValue<"">,
9+
Desc<"The path where symbol files should be cached. This defaults to LLDB's system cache location.">;
10+
def Timeout : Property<"timeout", "UInt64">,
11+
DefaultUnsignedValue<0>,
12+
Desc<"Timeout (in seconds) for requests made to a DEBUGINFOD server. A value of zero means we use the debuginfod default timeout: DEBUGINFOD_TIMEOUT if the environment variable is set and 90 seconds otherwise.">;
713
}

llvm/include/llvm/Debuginfod/Debuginfod.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ bool canUseDebuginfod();
4646
/// environment variable.
4747
SmallVector<StringRef> getDefaultDebuginfodUrls();
4848

49+
/// Returns the cache key for a given debuginfod URL path.
50+
std::string getDebuginfodCacheKey(StringRef UrlPath);
51+
4952
/// Sets the list of debuginfod server URLs to query. This overrides the
5053
/// environment variable DEBUGINFOD_URLS.
5154
void setDefaultDebuginfodUrls(const SmallVector<StringRef> &URLs);
@@ -58,15 +61,26 @@ Expected<std::string> getDefaultDebuginfodCacheDirectory();
5861
/// DEBUGINFOD_TIMEOUT environment variable, default is 90 seconds (90000 ms).
5962
std::chrono::milliseconds getDefaultDebuginfodTimeout();
6063

64+
/// Get the full URL path for a source request of a given BuildID and file
65+
/// path.
66+
std::string getDebuginfodSourceUrlPath(object::BuildIDRef ID,
67+
StringRef SourceFilePath);
68+
6169
/// Fetches a specified source file by searching the default local cache
6270
/// directory and server URLs.
6371
Expected<std::string> getCachedOrDownloadSource(object::BuildIDRef ID,
6472
StringRef SourceFilePath);
6573

74+
/// Get the full URL path for an executable request of a given BuildID.
75+
std::string getDebuginfodExecutableUrlPath(object::BuildIDRef ID);
76+
6677
/// Fetches an executable by searching the default local cache directory and
6778
/// server URLs.
6879
Expected<std::string> getCachedOrDownloadExecutable(object::BuildIDRef ID);
6980

81+
/// Get the full URL path for a debug binary request of a given BuildID.
82+
std::string getDebuginfodDebuginfoUrlPath(object::BuildIDRef ID);
83+
7084
/// Fetches a debug binary by searching the default local cache directory and
7185
/// server URLs.
7286
Expected<std::string> getCachedOrDownloadDebuginfo(object::BuildIDRef ID);

llvm/lib/Debuginfod/Debuginfod.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ std::optional<SmallVector<StringRef>> DebuginfodUrls;
5454
llvm::sys::RWMutex UrlsMutex;
5555
} // namespace
5656

57-
static std::string uniqueKey(llvm::StringRef S) {
57+
std::string getDebuginfodCacheKey(llvm::StringRef S) {
5858
return utostr(xxh3_64bits(S));
5959
}
6060

@@ -72,7 +72,7 @@ SmallVector<StringRef> getDefaultDebuginfodUrls() {
7272
std::shared_lock<llvm::sys::RWMutex> ReadGuard(UrlsMutex);
7373
if (!DebuginfodUrls) {
7474
// Only read from the environment variable if the user hasn't already
75-
// set the value
75+
// set the value.
7676
ReadGuard.unlock();
7777
std::unique_lock<llvm::sys::RWMutex> WriteGuard(UrlsMutex);
7878
DebuginfodUrls = SmallVector<StringRef>();
@@ -86,7 +86,7 @@ SmallVector<StringRef> getDefaultDebuginfodUrls() {
8686
return DebuginfodUrls.value();
8787
}
8888

89-
// Set the default debuginfod URL list, override the environment variable
89+
// Set the default debuginfod URL list, override the environment variable.
9090
void setDefaultDebuginfodUrls(const SmallVector<StringRef> &URLs) {
9191
std::unique_lock<llvm::sys::RWMutex> WriteGuard(UrlsMutex);
9292
DebuginfodUrls = URLs;
@@ -120,27 +120,43 @@ std::chrono::milliseconds getDefaultDebuginfodTimeout() {
120120
/// cache and return the cached file path. They first search the local cache,
121121
/// followed by the debuginfod servers.
122122

123-
Expected<std::string> getCachedOrDownloadSource(BuildIDRef ID,
124-
StringRef SourceFilePath) {
123+
std::string getDebuginfodSourceUrlPath(BuildIDRef ID,
124+
StringRef SourceFilePath) {
125125
SmallString<64> UrlPath;
126126
sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
127127
buildIDToString(ID), "source",
128128
sys::path::convert_to_slash(SourceFilePath));
129-
return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
129+
return std::string(UrlPath);
130130
}
131131

132-
Expected<std::string> getCachedOrDownloadExecutable(BuildIDRef ID) {
132+
Expected<std::string> getCachedOrDownloadSource(BuildIDRef ID,
133+
StringRef SourceFilePath) {
134+
std::string UrlPath = getDebuginfodSourceUrlPath(ID, SourceFilePath);
135+
return getCachedOrDownloadArtifact(getDebuginfodCacheKey(UrlPath), UrlPath);
136+
}
137+
138+
std::string getDebuginfodExecutableUrlPath(BuildIDRef ID) {
133139
SmallString<64> UrlPath;
134140
sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
135141
buildIDToString(ID), "executable");
136-
return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
142+
return std::string(UrlPath);
137143
}
138144

139-
Expected<std::string> getCachedOrDownloadDebuginfo(BuildIDRef ID) {
145+
Expected<std::string> getCachedOrDownloadExecutable(BuildIDRef ID) {
146+
std::string UrlPath = getDebuginfodExecutableUrlPath(ID);
147+
return getCachedOrDownloadArtifact(getDebuginfodCacheKey(UrlPath), UrlPath);
148+
}
149+
150+
std::string getDebuginfodDebuginfoUrlPath(BuildIDRef ID) {
140151
SmallString<64> UrlPath;
141152
sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
142153
buildIDToString(ID), "debuginfo");
143-
return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
154+
return std::string(UrlPath);
155+
}
156+
157+
Expected<std::string> getCachedOrDownloadDebuginfo(BuildIDRef ID) {
158+
std::string UrlPath = getDebuginfodDebuginfoUrlPath(ID);
159+
return getCachedOrDownloadArtifact(getDebuginfodCacheKey(UrlPath), UrlPath);
144160
}
145161

146162
// General fetching function.

0 commit comments

Comments
 (0)