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