1 //===-- llvm-debuginfod.cpp - federating debuginfod server ----------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file contains the llvm-debuginfod tool, which serves the debuginfod
11 /// protocol over HTTP. The tool periodically scans zero or more filesystem
12 /// directories for ELF binaries to serve, and federates requests for unknown
13 /// build IDs to the debuginfod servers set in the DEBUGINFOD_URLS environment
16 //===----------------------------------------------------------------------===//
18 #include "llvm/Debuginfod/Debuginfod.h"
19 #include "llvm/Debuginfod/HTTPClient.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/InitLLVM.h"
22 #include "llvm/Support/ThreadPool.h"
26 cl::OptionCategory
DebuginfodCategory("llvm-debuginfod Options");
28 static cl::list
<std::string
> ScanPaths(cl::Positional
,
29 cl::desc("<Directories to scan>"),
30 cl::cat(DebuginfodCategory
));
32 static cl::opt
<unsigned>
33 Port("p", cl::init(0),
34 cl::desc("Port to listen on. Set to 0 to bind to any available port."),
35 cl::cat(DebuginfodCategory
));
37 static cl::opt
<std::string
>
38 HostInterface("i", cl::init("0.0.0.0"),
39 cl::desc("Host interface to bind to."),
40 cl::cat(DebuginfodCategory
));
43 ScanInterval("t", cl::init(300),
44 cl::desc("Number of seconds to wait between subsequent "
45 "automated scans of the filesystem."),
46 cl::cat(DebuginfodCategory
));
48 static cl::opt
<double> MinInterval(
51 "Minimum number of seconds to wait before an on-demand update can be "
52 "triggered by a request for a buildid which is not in the collection."),
53 cl::cat(DebuginfodCategory
));
55 static cl::opt
<size_t>
56 MaxConcurrency("c", cl::init(0),
57 cl::desc("Maximum number of files to scan concurrently. If "
58 "0, use the hardware concurrency."),
59 cl::cat(DebuginfodCategory
));
61 static cl::opt
<bool> VerboseLogging("v", cl::init(false),
62 cl::desc("Enable verbose logging."),
63 cl::cat(DebuginfodCategory
));
65 ExitOnError ExitOnErr
;
67 int main(int argc
, char **argv
) {
68 InitLLVM
X(argc
, argv
);
69 HTTPClient::initialize();
70 cl::HideUnrelatedOptions({&DebuginfodCategory
});
71 cl::ParseCommandLineOptions(argc
, argv
);
73 SmallVector
<StringRef
, 1> Paths
;
74 for (const std::string
&Path
: ScanPaths
)
75 Paths
.push_back(Path
);
77 ThreadPool
Pool(hardware_concurrency(MaxConcurrency
));
79 DebuginfodCollection
Collection(Paths
, Log
, Pool
, MinInterval
);
80 DebuginfodServer
Server(Log
, Collection
);
83 Port
= ExitOnErr(Server
.Server
.bind(HostInterface
.c_str()));
85 ExitOnErr(Server
.Server
.bind(Port
, HostInterface
.c_str()));
87 Log
.push("Listening on port " + Twine(Port
).str());
89 Pool
.async([&]() { ExitOnErr(Server
.Server
.listen()); });
92 DebuginfodLogEntry Entry
= Log
.pop();
94 outs() << Entry
.Message
<< "\n";
100 ExitOnErr(Collection
.updateForever(std::chrono::seconds(ScanInterval
)));
102 llvm_unreachable("The ThreadPool should never finish running its tasks.");