LLVM 17.0.0git
Debuginfod.cpp
Go to the documentation of this file.
1//===-- llvm/Debuginfod/Debuginfod.cpp - Debuginfod client library --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10///
11/// This file contains several definitions for the debuginfod client and server.
12/// For the client, this file defines the fetchInfo function. For the server,
13/// this file defines the DebuginfodLogEntry and DebuginfodServer structs, as
14/// well as the DebuginfodLog, DebuginfodCollection classes. The fetchInfo
15/// function retrieves any of the three supported artifact types: (executable,
16/// debuginfo, source file) associated with a build-id from debuginfod servers.
17/// If a source file is to be fetched, its absolute path must be specified in
18/// the Description argument to fetchInfo. The DebuginfodLogEntry,
19/// DebuginfodLog, and DebuginfodCollection are used by the DebuginfodServer to
20/// scan the local filesystem for binaries and serve the debuginfod protocol.
21///
22//===----------------------------------------------------------------------===//
23
26#include "llvm/ADT/StringRef.h"
31#include "llvm/Object/BuildID.h"
35#include "llvm/Support/Errc.h"
36#include "llvm/Support/Error.h"
39#include "llvm/Support/Path.h"
41#include "llvm/Support/xxhash.h"
42
43#include <atomic>
44#include <thread>
45
46namespace llvm {
47
49
50static std::string uniqueKey(llvm::StringRef S) { return utostr(xxHash64(S)); }
51
52// Returns a binary BuildID as a normalized hex string.
53// Uses lowercase for compatibility with common debuginfod servers.
54static std::string buildIDToString(BuildIDRef ID) {
55 return llvm::toHex(ID, /*LowerCase=*/true);
56}
57
60}
61
63 const char *DebuginfodUrlsEnv = std::getenv("DEBUGINFOD_URLS");
64 if (DebuginfodUrlsEnv == nullptr)
66
67 SmallVector<StringRef> DebuginfodUrls;
68 StringRef(DebuginfodUrlsEnv).split(DebuginfodUrls, " ");
69 return DebuginfodUrls;
70}
71
72/// Finds a default local file caching directory for the debuginfod client,
73/// first checking DEBUGINFOD_CACHE_PATH.
75 if (const char *CacheDirectoryEnv = std::getenv("DEBUGINFOD_CACHE_PATH"))
76 return CacheDirectoryEnv;
77
78 SmallString<64> CacheDirectory;
79 if (!sys::path::cache_directory(CacheDirectory))
80 return createStringError(
81 errc::io_error, "Unable to determine appropriate cache directory.");
82 sys::path::append(CacheDirectory, "llvm-debuginfod", "client");
83 return std::string(CacheDirectory);
84}
85
86std::chrono::milliseconds getDefaultDebuginfodTimeout() {
87 long Timeout;
88 const char *DebuginfodTimeoutEnv = std::getenv("DEBUGINFOD_TIMEOUT");
89 if (DebuginfodTimeoutEnv &&
90 to_integer(StringRef(DebuginfodTimeoutEnv).trim(), Timeout, 10))
91 return std::chrono::milliseconds(Timeout * 1000);
92
93 return std::chrono::milliseconds(90 * 1000);
94}
95
96/// The following functions fetch a debuginfod artifact to a file in a local
97/// cache and return the cached file path. They first search the local cache,
98/// followed by the debuginfod servers.
99
101 StringRef SourceFilePath) {
102 SmallString<64> UrlPath;
103 sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
104 buildIDToString(ID), "source",
105 sys::path::convert_to_slash(SourceFilePath));
106 return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
107}
108
110 SmallString<64> UrlPath;
111 sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
112 buildIDToString(ID), "executable");
113 return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
114}
115
117 SmallString<64> UrlPath;
118 sys::path::append(UrlPath, sys::path::Style::posix, "buildid",
119 buildIDToString(ID), "debuginfo");
120 return getCachedOrDownloadArtifact(uniqueKey(UrlPath), UrlPath);
121}
122
123// General fetching function.
125 StringRef UrlPath) {
126 SmallString<10> CacheDir;
127
129 if (!CacheDirOrErr)
130 return CacheDirOrErr.takeError();
131 CacheDir = *CacheDirOrErr;
132
133 return getCachedOrDownloadArtifact(UniqueKey, UrlPath, CacheDir,
136}
137
138namespace {
139
140/// A simple handler which streams the returned data to a cache file. The cache
141/// file is only created if a 200 OK status is observed.
142class StreamedHTTPResponseHandler : public HTTPResponseHandler {
143 using CreateStreamFn =
144 std::function<Expected<std::unique_ptr<CachedFileStream>>()>;
145 CreateStreamFn CreateStream;
146 HTTPClient &Client;
147 std::unique_ptr<CachedFileStream> FileStream;
148
149public:
150 StreamedHTTPResponseHandler(CreateStreamFn CreateStream, HTTPClient &Client)
151 : CreateStream(CreateStream), Client(Client) {}
152 virtual ~StreamedHTTPResponseHandler() = default;
153
154 Error handleBodyChunk(StringRef BodyChunk) override;
155};
156
157} // namespace
158
159Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) {
160 if (!FileStream) {
161 unsigned Code = Client.responseCode();
162 if (Code && Code != 200)
163 return Error::success();
164 Expected<std::unique_ptr<CachedFileStream>> FileStreamOrError =
165 CreateStream();
166 if (!FileStreamOrError)
167 return FileStreamOrError.takeError();
168 FileStream = std::move(*FileStreamOrError);
169 }
170 *FileStream->OS << BodyChunk;
171 return Error::success();
172}
173
174// An over-accepting simplification of the HTTP RFC 7230 spec.
175static bool isHeader(StringRef S) {
178 std::tie(Name, Value) = S.split(':');
179 if (Name.empty() || Value.empty())
180 return false;
181 return all_of(Name, [](char C) { return llvm::isPrint(C) && C != ' '; }) &&
182 all_of(Value, [](char C) { return llvm::isPrint(C) || C == '\t'; });
183}
184
186 const char *Filename = getenv("DEBUGINFOD_HEADERS_FILE");
187 if (!Filename)
188 return {};
190 MemoryBuffer::getFile(Filename, /*IsText=*/true);
191 if (!HeadersFile)
192 return {};
193
195 uint64_t LineNumber = 0;
196 for (StringRef Line : llvm::split((*HeadersFile)->getBuffer(), '\n')) {
197 LineNumber++;
198 if (!Line.empty() && Line.back() == '\r')
199 Line = Line.drop_back();
200 if (!isHeader(Line)) {
201 if (!all_of(Line, llvm::isSpace))
203 << "could not parse debuginfod header: " << Filename << ':'
204 << LineNumber << '\n';
205 continue;
206 }
207 Headers.emplace_back(Line);
208 }
209 return Headers;
210}
211
213 StringRef UniqueKey, StringRef UrlPath, StringRef CacheDirectoryPath,
214 ArrayRef<StringRef> DebuginfodUrls, std::chrono::milliseconds Timeout) {
215 SmallString<64> AbsCachedArtifactPath;
216 sys::path::append(AbsCachedArtifactPath, CacheDirectoryPath,
217 "llvmcache-" + UniqueKey);
218
219 Expected<FileCache> CacheOrErr =
220 localCache("Debuginfod-client", ".debuginfod-client", CacheDirectoryPath);
221 if (!CacheOrErr)
222 return CacheOrErr.takeError();
223
224 FileCache Cache = *CacheOrErr;
225 // We choose an arbitrary Task parameter as we do not make use of it.
226 unsigned Task = 0;
227 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey, "");
228 if (!CacheAddStreamOrErr)
229 return CacheAddStreamOrErr.takeError();
230 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
231 if (!CacheAddStream)
232 return std::string(AbsCachedArtifactPath);
233 // The artifact was not found in the local cache, query the debuginfod
234 // servers.
237 "No working HTTP client is available.");
238
240 return createStringError(
242 "A working HTTP client is available, but it is not initialized. To "
243 "allow Debuginfod to make HTTP requests, call HTTPClient::initialize() "
244 "at the beginning of main.");
245
246 HTTPClient Client;
247 Client.setTimeout(Timeout);
248 for (StringRef ServerUrl : DebuginfodUrls) {
249 SmallString<64> ArtifactUrl;
250 sys::path::append(ArtifactUrl, sys::path::Style::posix, ServerUrl, UrlPath);
251
252 // Perform the HTTP request and if successful, write the response body to
253 // the cache.
254 {
255 StreamedHTTPResponseHandler Handler(
256 [&]() { return CacheAddStream(Task, ""); }, Client);
257 HTTPRequest Request(ArtifactUrl);
258 Request.Headers = getHeaders();
259 Error Err = Client.perform(Request, Handler);
260 if (Err)
261 return std::move(Err);
262
263 unsigned Code = Client.responseCode();
264 if (Code && Code != 200)
265 continue;
266 }
267
268 Expected<CachePruningPolicy> PruningPolicyOrErr =
269 parseCachePruningPolicy(std::getenv("DEBUGINFOD_CACHE_POLICY"));
270 if (!PruningPolicyOrErr)
271 return PruningPolicyOrErr.takeError();
272 pruneCache(CacheDirectoryPath, *PruningPolicyOrErr);
273
274 // Return the path to the artifact on disk.
275 return std::string(AbsCachedArtifactPath);
276 }
277
278 return createStringError(errc::argument_out_of_domain, "build id not found");
279}
280
282 : Message(Message.str()) {}
283
284void DebuginfodLog::push(const Twine &Message) {
285 push(DebuginfodLogEntry(Message));
286}
287
289 {
290 std::lock_guard<std::mutex> Guard(QueueMutex);
291 LogEntryQueue.push(Entry);
292 }
293 QueueCondition.notify_one();
294}
295
297 {
298 std::unique_lock<std::mutex> Guard(QueueMutex);
299 // Wait for messages to be pushed into the queue.
300 QueueCondition.wait(Guard, [&] { return !LogEntryQueue.empty(); });
301 }
302 std::lock_guard<std::mutex> Guard(QueueMutex);
303 if (!LogEntryQueue.size())
304 llvm_unreachable("Expected message in the queue.");
305
306 DebuginfodLogEntry Entry = LogEntryQueue.front();
307 LogEntryQueue.pop();
308 return Entry;
309}
310
312 DebuginfodLog &Log, ThreadPool &Pool,
313 double MinInterval)
314 : Log(Log), Pool(Pool), MinInterval(MinInterval) {
315 for (StringRef Path : PathsRef)
316 Paths.push_back(Path.str());
317}
318
320 std::lock_guard<sys::Mutex> Guard(UpdateMutex);
321 if (UpdateTimer.isRunning())
322 UpdateTimer.stopTimer();
323 UpdateTimer.clear();
324 for (const std::string &Path : Paths) {
325 Log.push("Updating binaries at path " + Path);
326 if (Error Err = findBinaries(Path))
327 return Err;
328 }
329 Log.push("Updated collection");
330 UpdateTimer.startTimer();
331 return Error::success();
332}
333
334Expected<bool> DebuginfodCollection::updateIfStale() {
335 if (!UpdateTimer.isRunning())
336 return false;
337 UpdateTimer.stopTimer();
338 double Time = UpdateTimer.getTotalTime().getWallTime();
339 UpdateTimer.startTimer();
340 if (Time < MinInterval)
341 return false;
342 if (Error Err = update())
343 return std::move(Err);
344 return true;
345}
346
348 while (true) {
349 if (Error Err = update())
350 return Err;
351 std::this_thread::sleep_for(Interval);
352 }
353 llvm_unreachable("updateForever loop should never end");
354}
355
356static bool hasELFMagic(StringRef FilePath) {
358 std::error_code EC = identify_magic(FilePath, Type);
359 if (EC)
360 return false;
361 switch (Type) {
362 case file_magic::elf:
367 return true;
368 default:
369 return false;
370 }
371}
372
373Error DebuginfodCollection::findBinaries(StringRef Path) {
374 std::error_code EC;
375 sys::fs::recursive_directory_iterator I(Twine(Path), EC), E;
376 std::mutex IteratorMutex;
377 ThreadPoolTaskGroup IteratorGroup(Pool);
378 for (unsigned WorkerIndex = 0; WorkerIndex < Pool.getThreadCount();
379 WorkerIndex++) {
380 IteratorGroup.async([&, this]() -> void {
381 std::string FilePath;
382 while (true) {
383 {
384 // Check if iteration is over or there is an error during iteration
385 std::lock_guard<std::mutex> Guard(IteratorMutex);
386 if (I == E || EC)
387 return;
388 // Grab a file path from the directory iterator and advance the
389 // iterator.
390 FilePath = I->path();
391 I.increment(EC);
392 }
393
394 // Inspect the file at this path to determine if it is debuginfo.
395 if (!hasELFMagic(FilePath))
396 continue;
397
398 Expected<object::OwningBinary<object::Binary>> BinOrErr =
399 object::createBinary(FilePath);
400
401 if (!BinOrErr) {
402 consumeError(BinOrErr.takeError());
403 continue;
404 }
405 object::Binary *Bin = std::move(BinOrErr.get().getBinary());
406 if (!Bin->isObject())
407 continue;
408
409 // TODO: Support non-ELF binaries
410 object::ELFObjectFileBase *Object =
411 dyn_cast<object::ELFObjectFileBase>(Bin);
412 if (!Object)
413 continue;
414
415 std::optional<BuildIDRef> ID = getBuildID(Object);
416 if (!ID)
417 continue;
418
419 std::string IDString = buildIDToString(*ID);
420 if (Object->hasDebugInfo()) {
421 std::lock_guard<sys::RWMutex> DebugBinariesGuard(DebugBinariesMutex);
422 (void)DebugBinaries.try_emplace(IDString, std::move(FilePath));
423 } else {
424 std::lock_guard<sys::RWMutex> BinariesGuard(BinariesMutex);
425 (void)Binaries.try_emplace(IDString, std::move(FilePath));
426 }
427 }
428 });
429 }
430 IteratorGroup.wait();
431 std::unique_lock<std::mutex> Guard(IteratorMutex);
432 if (EC)
433 return errorCodeToError(EC);
434 return Error::success();
435}
436
437Expected<std::optional<std::string>>
438DebuginfodCollection::getBinaryPath(BuildIDRef ID) {
439 Log.push("getting binary path of ID " + buildIDToString(ID));
440 std::shared_lock<sys::RWMutex> Guard(BinariesMutex);
441 auto Loc = Binaries.find(buildIDToString(ID));
442 if (Loc != Binaries.end()) {
443 std::string Path = Loc->getValue();
444 return Path;
445 }
446 return std::nullopt;
447}
448
449Expected<std::optional<std::string>>
450DebuginfodCollection::getDebugBinaryPath(BuildIDRef ID) {
451 Log.push("getting debug binary path of ID " + buildIDToString(ID));
452 std::shared_lock<sys::RWMutex> Guard(DebugBinariesMutex);
453 auto Loc = DebugBinaries.find(buildIDToString(ID));
454 if (Loc != DebugBinaries.end()) {
455 std::string Path = Loc->getValue();
456 return Path;
457 }
458 return std::nullopt;
459}
460
462 {
463 // Check collection; perform on-demand update if stale.
464 Expected<std::optional<std::string>> PathOrErr = getBinaryPath(ID);
465 if (!PathOrErr)
466 return PathOrErr.takeError();
467 std::optional<std::string> Path = *PathOrErr;
468 if (!Path) {
469 Expected<bool> UpdatedOrErr = updateIfStale();
470 if (!UpdatedOrErr)
471 return UpdatedOrErr.takeError();
472 if (*UpdatedOrErr) {
473 // Try once more.
474 PathOrErr = getBinaryPath(ID);
475 if (!PathOrErr)
476 return PathOrErr.takeError();
477 Path = *PathOrErr;
478 }
479 }
480 if (Path)
481 return *Path;
482 }
483
484 // Try federation.
486 if (!PathOrErr)
487 consumeError(PathOrErr.takeError());
488
489 // Fall back to debug binary.
490 return findDebugBinaryPath(ID);
491}
492
494 // Check collection; perform on-demand update if stale.
495 Expected<std::optional<std::string>> PathOrErr = getDebugBinaryPath(ID);
496 if (!PathOrErr)
497 return PathOrErr.takeError();
498 std::optional<std::string> Path = *PathOrErr;
499 if (!Path) {
500 Expected<bool> UpdatedOrErr = updateIfStale();
501 if (!UpdatedOrErr)
502 return UpdatedOrErr.takeError();
503 if (*UpdatedOrErr) {
504 // Try once more.
505 PathOrErr = getBinaryPath(ID);
506 if (!PathOrErr)
507 return PathOrErr.takeError();
508 Path = *PathOrErr;
509 }
510 }
511 if (Path)
512 return *Path;
513
514 // Try federation.
516}
517
519 DebuginfodCollection &Collection)
520 : Log(Log), Collection(Collection) {
521 cantFail(
522 Server.get(R"(/buildid/(.*)/debuginfo)", [&](HTTPServerRequest Request) {
523 Log.push("GET " + Request.UrlPath);
524 std::string IDString;
525 if (!tryGetFromHex(Request.UrlPathMatches[0], IDString)) {
526 Request.setResponse(
527 {404, "text/plain", "Build ID is not a hex string\n"});
528 return;
529 }
530 object::BuildID ID(IDString.begin(), IDString.end());
532 if (Error Err = PathOrErr.takeError()) {
533 consumeError(std::move(Err));
534 Request.setResponse({404, "text/plain", "Build ID not found\n"});
535 return;
536 }
537 streamFile(Request, *PathOrErr);
538 }));
539 cantFail(
540 Server.get(R"(/buildid/(.*)/executable)", [&](HTTPServerRequest Request) {
541 Log.push("GET " + Request.UrlPath);
542 std::string IDString;
543 if (!tryGetFromHex(Request.UrlPathMatches[0], IDString)) {
544 Request.setResponse(
545 {404, "text/plain", "Build ID is not a hex string\n"});
546 return;
547 }
548 object::BuildID ID(IDString.begin(), IDString.end());
549 Expected<std::string> PathOrErr = Collection.findBinaryPath(ID);
550 if (Error Err = PathOrErr.takeError()) {
551 consumeError(std::move(Err));
552 Request.setResponse({404, "text/plain", "Build ID not found\n"});
553 return;
554 }
555 streamFile(Request, *PathOrErr);
556 }));
557}
558
559} // namespace llvm
This file declares a library for handling Build IDs and using them to find debug info.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains several declarations for the debuginfod client and server.
std::string Name
This file contains the declarations of the HTTPClient library for issuing HTTP requests and handling ...
#define I(x, y, z)
Definition: MD5.cpp:58
if(VerifyEach)
This file contains some functions that are useful when dealing with strings.
Tracks a collection of debuginfod artifacts on the local filesystem.
Definition: Debuginfod.h:106
DebuginfodCollection(ArrayRef< StringRef > Paths, DebuginfodLog &Log, ThreadPool &Pool, double MinInterval)
Definition: Debuginfod.cpp:311
Expected< std::string > findBinaryPath(object::BuildIDRef)
Definition: Debuginfod.cpp:461
Error updateForever(std::chrono::milliseconds Interval)
Definition: Debuginfod.cpp:347
Expected< std::string > findDebugBinaryPath(object::BuildIDRef)
Definition: Debuginfod.cpp:493
DebuginfodLogEntry pop()
Definition: Debuginfod.cpp:296
void push(DebuginfodLogEntry Entry)
Definition: Debuginfod.cpp:288
Represents either an error or a value T.
Definition: ErrorOr.h:56
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
A reusable client that can perform HTTPRequests through a network socket.
Definition: HTTPClient.h:51
static bool isAvailable()
Returns true only if LLVM has been compiled with a working HTTPClient.
Definition: HTTPClient.cpp:143
static bool IsInitialized
Definition: HTTPClient.h:60
unsigned responseCode()
Returns the last received response code or zero if none.
Definition: HTTPClient.cpp:156
Error perform(const HTTPRequest &Request, HTTPResponseHandler &Handler)
Performs the Request, passing response data to the Handler.
Definition: HTTPClient.cpp:151
void setTimeout(std::chrono::milliseconds Timeout)
Sets the timeout for the entire request, in milliseconds.
Definition: HTTPClient.cpp:149
Error get(StringRef UrlPathPattern, HTTPRequestHandler Handler)
Registers a URL pattern routing rule.
Definition: HTTPServer.cpp:169
Interval Class - An Interval is a set of nodes defined such that every node in the interval has all o...
Definition: Interval.h:36
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
iterator end()
Definition: StringMap.h:204
iterator find(StringRef Key)
Definition: StringMap.h:217
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Definition: StringMap.h:340
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:687
A ThreadPool for asynchronous parallel execution on a defined number of threads.
Definition: ThreadPool.h:52
unsigned getThreadCount() const
Definition: ThreadPool.h:110
double getWallTime() const
Definition: Timer.h:45
bool isRunning() const
Check if the timer is currently running.
Definition: Timer.h:118
void stopTimer()
Stop the timer.
Definition: Timer.cpp:197
void clear()
Clear the timer state.
Definition: Timer.cpp:205
void startTimer()
Start the timer running.
Definition: Timer.cpp:190
TimeRecord getTotalTime() const
Return the duration for which this timer has been running.
Definition: Timer.h:135
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition: WithColor.cpp:85
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
std::optional< BuildIDRef > getBuildID(const ObjectFile *Obj)
Returns the build ID, if any, contained in the given object file.
Definition: BuildID.cpp:48
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:45
bool cache_directory(SmallVectorImpl< char > &result)
Get the directory where installed packages should put their machine-local cache, e....
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
Definition: Path.cpp:568
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:33
static std::string uniqueKey(llvm::StringRef S)
Definition: Debuginfod.cpp:50
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1819
Expected< std::string > getCachedOrDownloadExecutable(object::BuildIDRef ID)
Fetches an executable by searching the default local cache directory and server URLs.
static bool isHeader(StringRef S)
Definition: Debuginfod.cpp:175
SmallVector< StringRef > getDefaultDebuginfodUrls()
Finds default array of Debuginfod server URLs by checking DEBUGINFOD_URLS environment variable.
Definition: Debuginfod.cpp:62
std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
Definition: Caching.h:42
Expected< std::string > getCachedOrDownloadDebuginfo(object::BuildIDRef ID)
Fetches a debug binary by searching the default local cache directory and server URLs.
static std::string buildIDToString(BuildIDRef ID)
Definition: Debuginfod.cpp:54
Expected< CachePruningPolicy > parseCachePruningPolicy(StringRef PolicyStr)
Parse the given string as a cache pruning policy.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1246
@ argument_out_of_domain
Expected< std::string > getCachedOrDownloadArtifact(StringRef UniqueKey, StringRef UrlPath)
Fetches any debuginfod artifact using the default local cache directory and server URLs.
Definition: Debuginfod.cpp:124
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
Expected< std::string > getCachedOrDownloadSource(object::BuildIDRef ID, StringRef SourceFilePath)
Fetches a specified source file by searching the default local cache directory and server URLs.
bool pruneCache(StringRef Path, CachePruningPolicy Policy, const std::vector< std::unique_ptr< MemoryBuffer > > &Files={})
Peform pruning using the supplied policy, returns true if pruning occurred, i.e.
std::chrono::milliseconds getDefaultDebuginfodTimeout()
Finds a default timeout for debuginfod HTTP requests.
Definition: Debuginfod.cpp:86
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:92
static bool hasELFMagic(StringRef FilePath)
Definition: Debuginfod.cpp:356
bool streamFile(HTTPServerRequest &Request, StringRef FilePath)
Sets the response to stream the file at FilePath, if available, and otherwise an HTTP 404 error respo...
Definition: HTTPServer.cpp:31
static SmallVector< std::string, 0 > getHeaders()
Definition: Debuginfod.cpp:185
std::function< Expected< AddStreamFn >(unsigned Task, StringRef Key, const Twine &ModuleName)> FileCache
This is the type of a file cache.
Definition: Caching.h:58
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
Expected< FileCache > localCache(const Twine &CacheNameRef, const Twine &TempFilePrefixRef, const Twine &CacheDirectoryPathRef, AddBufferFn AddBuffer=[](size_t Task, const Twine &ModuleName, std::unique_ptr< MemoryBuffer > MB) {})
Create a local file system cache which uses the given cache name, temporary file prefix,...
Definition: Caching.cpp:29
bool canUseDebuginfod()
Returns false if a debuginfod lookup can be determined to have no chance of succeeding.
Definition: Debuginfod.cpp:58
Expected< std::string > getDefaultDebuginfodCacheDirectory()
Finds a default local file caching directory for the debuginfod client, first checking DEBUGINFOD_CAC...
Definition: Debuginfod.cpp:74
uint64_t xxHash64(llvm::StringRef Data)
Definition: xxhash.cpp:70
DebuginfodServer(DebuginfodLog &Log, DebuginfodCollection &Collection)
Definition: Debuginfod.cpp:518
DebuginfodCollection & Collection
Definition: Debuginfod.h:140
A stateless description of an outbound HTTP request.
Definition: HTTPClient.h:28
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:20
@ elf_relocatable
ELF Relocatable object file.
Definition: Magic.h:26
@ elf_shared_object
ELF dynamically linked shared lib.
Definition: Magic.h:28
@ elf_executable
ELF Executable image.
Definition: Magic.h:27
@ elf_core
ELF core image.
Definition: Magic.h:29
@ elf
ELF Unknown type.
Definition: Magic.h:25