1 //===-- llvm/Debuginfod/Debuginfod.h - Debuginfod client --------*- C++ -*-===//
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 /// This file contains several declarations for the debuginfod client and
11 /// server. The client functions are getDefaultDebuginfodUrls,
12 /// getCachedOrDownloadArtifact, and several convenience functions for specific
13 /// artifact types: getCachedOrDownloadSource, getCachedOrDownloadExecutable,
14 /// and getCachedOrDownloadDebuginfo. For the server, this file declares the
15 /// DebuginfodLogEntry and DebuginfodServer structs, as well as the
16 /// DebuginfodLog, DebuginfodCollection classes.
17 ///
18 //===----------------------------------------------------------------------===//
19 
20 #ifndef LLVM_DEBUGINFOD_DEBUGINFOD_H
21 #define LLVM_DEBUGINFOD_DEBUGINFOD_H
22 
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/StringMap.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Debuginfod/HTTPServer.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/Mutex.h"
30 #include "llvm/Support/RWMutex.h"
31 #include "llvm/Support/Timer.h"
32 
33 #include <chrono>
34 #include <condition_variable>
35 #include <queue>
36 
37 namespace llvm {
38 
39 typedef ArrayRef<uint8_t> BuildIDRef;
40 
41 typedef SmallVector<uint8_t, 10> BuildID;
42 
43 /// Finds default array of Debuginfod server URLs by checking DEBUGINFOD_URLS
44 /// environment variable.
45 Expected<SmallVector<StringRef>> getDefaultDebuginfodUrls();
46 
47 /// Finds a default local file caching directory for the debuginfod client,
48 /// first checking DEBUGINFOD_CACHE_PATH.
49 Expected<std::string> getDefaultDebuginfodCacheDirectory();
50 
51 /// Finds a default timeout for debuginfod HTTP requests. Checks
52 /// DEBUGINFOD_TIMEOUT environment variable, default is 90 seconds (90000 ms).
53 std::chrono::milliseconds getDefaultDebuginfodTimeout();
54 
55 /// Fetches a specified source file by searching the default local cache
56 /// directory and server URLs.
57 Expected<std::string> getCachedOrDownloadSource(BuildIDRef ID,
58                                                 StringRef SourceFilePath);
59 
60 /// Fetches an executable by searching the default local cache directory and
61 /// server URLs.
62 Expected<std::string> getCachedOrDownloadExecutable(BuildIDRef ID);
63 
64 /// Fetches a debug binary by searching the default local cache directory and
65 /// server URLs.
66 Expected<std::string> getCachedOrDownloadDebuginfo(BuildIDRef ID);
67 
68 /// Fetches any debuginfod artifact using the default local cache directory and
69 /// server URLs.
70 Expected<std::string> getCachedOrDownloadArtifact(StringRef UniqueKey,
71                                                   StringRef UrlPath);
72 
73 /// Fetches any debuginfod artifact using the specified local cache directory,
74 /// server URLs, and request timeout (in milliseconds). If the artifact is
75 /// found, uses the UniqueKey for the local cache file.
76 Expected<std::string> getCachedOrDownloadArtifact(
77     StringRef UniqueKey, StringRef UrlPath, StringRef CacheDirectoryPath,
78     ArrayRef<StringRef> DebuginfodUrls, std::chrono::milliseconds Timeout);
79 
80 class ThreadPool;
81 
82 struct DebuginfodLogEntry {
83   std::string Message;
84   DebuginfodLogEntry() = default;
85   DebuginfodLogEntry(const Twine &Message);
86 };
87 
88 class DebuginfodLog {
89   std::mutex QueueMutex;
90   std::condition_variable QueueCondition;
91   std::queue<DebuginfodLogEntry> LogEntryQueue;
92 
93 public:
94   // Adds a log entry to end of the queue.
95   void push(DebuginfodLogEntry Entry);
96   // Adds a log entry to end of the queue.
97   void push(const Twine &Message);
98   // Blocks until there are log entries in the queue, then pops and returns the
99   // first one.
100   DebuginfodLogEntry pop();
101 };
102 
103 /// Tracks a collection of debuginfod artifacts on the local filesystem.
104 class DebuginfodCollection {
105   SmallVector<std::string, 1> Paths;
106   sys::RWMutex BinariesMutex;
107   StringMap<std::string> Binaries;
108   sys::RWMutex DebugBinariesMutex;
109   StringMap<std::string> DebugBinaries;
110   Error findBinaries(StringRef Path);
111   Expected<Optional<std::string>> getDebugBinaryPath(BuildIDRef);
112   Expected<Optional<std::string>> getBinaryPath(BuildIDRef);
113   // If the collection has not been updated since MinInterval, call update() and
114   // return true. Otherwise return false. If update returns an error, return the
115   // error.
116   Expected<bool> updateIfStale();
117   DebuginfodLog &Log;
118   ThreadPool &Pool;
119   Timer UpdateTimer;
120   sys::Mutex UpdateMutex;
121 
122   // Minimum update interval, in seconds, for on-demand updates triggered when a
123   // build-id is not found.
124   double MinInterval;
125 
126 public:
127   DebuginfodCollection(ArrayRef<StringRef> Paths, DebuginfodLog &Log,
128                        ThreadPool &Pool, double MinInterval);
129   Error update();
130   Error updateForever(std::chrono::milliseconds Interval);
131   Expected<std::string> findDebugBinaryPath(BuildIDRef);
132   Expected<std::string> findBinaryPath(BuildIDRef);
133 };
134 
135 struct DebuginfodServer {
136   HTTPServer Server;
137   DebuginfodLog &Log;
138   DebuginfodCollection &Collection;
139   DebuginfodServer(DebuginfodLog &Log, DebuginfodCollection &Collection);
140 };
141 
142 } // end namespace llvm
143 
144 #endif
145