LLVM 22.0.0git
Debug.cpp
Go to the documentation of this file.
1//===-- Debug.cpp - An easy way to add debug output to your code ----------===//
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// This file implements a handy way of adding debugging information to your
10// code, without it being enabled all of the time, and without having to add
11// command line options to enable it.
12//
13// In particular, just wrap your code with the LLVM_DEBUG() macro, and it will
14// be enabled automatically if you specify '-debug' on the command-line.
15// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
16// that your debug code belongs to class "foo". Then, on the command line, you
17// can specify '-debug-only=foo' to enable JUST the debug information for the
18// foo class.
19//
20// When compiling without assertions, the -debug-* options and all code in
21// LLVM_DEBUG() statements disappears, so it does not affect the runtime of the
22// code.
23//
24//===----------------------------------------------------------------------===//
25
26#include "llvm/Support/Debug.h"
33#include <utility>
34
35#include "DebugOptions.h"
36
37#undef isCurrentDebugType
38#undef setCurrentDebugType
39#undef setCurrentDebugTypes
40
41using namespace llvm;
42
43/// Parse a debug type string into a pair of the debug type and the debug level.
44/// The expected format is "type[:level]", where the level is an optional
45/// integer.
46static std::pair<std::string, std::optional<int>>
48 std::optional<int> Level;
49 size_t ColonPos = DbgType.find(':');
50 if (ColonPos != StringRef::npos) {
51 StringRef LevelStr = DbgType.substr(ColonPos + 1);
52 DbgType = DbgType.take_front(ColonPos);
53 if (LevelStr.empty())
54 Level = 0;
55 else {
56 int parsedLevel;
57 if (to_integer(LevelStr, parsedLevel, 10))
58 Level = parsedLevel;
59 }
60 }
61 return std::make_pair(DbgType.str(), Level);
62}
63
64// Even though LLVM might be built with NDEBUG, define symbols that the code
65// built without NDEBUG can depend on via the llvm/Support/Debug.h header.
66namespace llvm {
67/// Exported boolean set by the -debug option.
68bool DebugFlag = false;
69
70/// The current debug type and an optional debug level.
71/// The debug level is the verbosity of the debug output.
72/// 0 is a special level that acts as an opt-out for this specific debug type.
73/// If provided, the debug output is enabled only if the user specified a level
74/// at least as high as the provided level.
77
78/// Return true if the specified string is the debug type
79/// specified on the command line, or if none was specified on the command line
80/// with the -debug-only=X option.
81bool isCurrentDebugType(const char *DebugType, int Level) {
82 if (CurrentDebugType->empty())
83 return true;
84 // Track if there is at least one debug type with a level, this is used
85 // to allow to opt-out of some DebugType and leaving all the others enabled.
86 bool HasEnabledDebugType = false;
87 // See if DebugType is in list. Note: do not use find() as that forces us to
88 // unnecessarily create an std::string instance.
89 for (auto &D : *CurrentDebugType) {
90 HasEnabledDebugType =
91 HasEnabledDebugType || (!D.second.has_value() || D.second.value() > 0);
92 if (D.first != DebugType)
93 continue;
94 if (!D.second.has_value())
95 return true;
96 return D.second >= Level;
97 }
98 return !HasEnabledDebugType;
99}
100
101/// Set the current debug type, as if the -debug-only=X
102/// option were specified. Note that DebugFlag also needs to be set to true for
103/// debug output to be produced.
104///
105void setCurrentDebugTypes(const char **Types, unsigned Count);
106
107void setCurrentDebugType(const char *Type) {
109}
110
111void setCurrentDebugTypes(const char **Types, unsigned Count) {
112 CurrentDebugType->clear();
113 CurrentDebugType->reserve(Count);
114 for (const char *Type : ArrayRef(Types, Count))
116}
117
118} // namespace llvm
119
120// All Debug.h functionality is a no-op in NDEBUG mode.
121#ifndef NDEBUG
122
123namespace {
124struct CreateDebug {
125 static void *call() {
126 return new cl::opt<bool, true>("debug", cl::desc("Enable debug output"),
128 }
129};
130
131// -debug-buffer-size - Buffer the last N characters of debug output
132//until program termination.
133struct CreateDebugBufferSize {
134 static void *call() {
135 return new cl::opt<unsigned>(
136 "debug-buffer-size",
137 cl::desc("Buffer the last N characters of debug output "
138 "until program termination. "
139 "[default 0 -- immediate print-out]"),
140 cl::Hidden, cl::init(0));
141 }
142};
143} // namespace
144
145// -debug - Command line option to enable the DEBUG statements in the passes.
146// This flag may only be enabled in debug builds.
149
150namespace {
151
152struct DebugOnlyOpt {
153 void operator=(const std::string &Val) const {
154 if (Val.empty())
155 return;
156 DebugFlag = true;
158 StringRef(Val).split(DbgTypes, ',', -1, false);
159 for (auto DbgType : DbgTypes)
160 CurrentDebugType->push_back(parseDebugType(DbgType));
161 }
162};
163} // namespace
164
165static DebugOnlyOpt DebugOnlyOptLoc;
166
167namespace {
168struct CreateDebugOnly {
169 static void *call() {
171 "debug-only",
172 cl::desc(
173 "Enable a specific type of debug output (comma separated list "
174 "of types using the format \"type[:level]\", where the level "
175 "is an optional integer. The level can be set to 1, 2, 3, etc. to "
176 "control the verbosity of the output. Setting a debug-type level "
177 "to zero acts as an opt-out for this specific debug-type without "
178 "affecting the others."),
179 cl::Hidden, cl::value_desc("debug string"),
181 }
182};
183} // namespace
184
186 CreateDebugOnly>
188
190 *Debug;
192 *DebugOnly;
193}
194
195// Signal handlers - dump debug output on termination.
196static void debug_user_sig_handler(void *Cookie) {
197 // This is a bit sneaky. Since this is under #ifndef NDEBUG, we
198 // know that debug mode is enabled and dbgs() really is a
199 // circular_raw_ostream. If NDEBUG is defined, then dbgs() ==
200 // errs() but this will never be invoked.
202 static_cast<circular_raw_ostream &>(llvm::dbgs());
203 dbgout.flushBufferWithBanner();
204}
205
206/// dbgs - Return a circular-buffered debug stream.
208 // Do one-time initialization in a thread-safe way.
209 static struct dbgstream {
211
212 dbgstream()
213 : strm(errs(), "*** Debug Log Output ***\n",
216 // TODO: Add a handler for SIGUSER1-type signals so the user can
217 // force a debug dump.
219 // Otherwise we've already set the debug stream buffer size to
220 // zero, disabling buffering so it will output directly to errs().
221 }
222 } thestrm;
223
224 return thestrm.strm;
225}
226
227#else
228// Avoid "has no symbols" warning.
229namespace llvm {
230 /// dbgs - Return errs().
231 raw_ostream &dbgs() {
232 return errs();
233 }
234}
236#endif
237
238/// EnableDebugBuffering - Turn on signal handler installation.
239///
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
Definition: Debug.cpp:147
static void debug_user_sig_handler(void *Cookie)
Definition: Debug.cpp:196
static ManagedStatic< cl::opt< unsigned >, CreateDebugBufferSize > DebugBufferSize
Definition: Debug.cpp:148
static std::pair< std::string, std::optional< int > > parseDebugType(StringRef DbgType)
Parse a debug type string into a pair of the debug type and the debug level.
Definition: Debug.cpp:47
static ManagedStatic< cl::opt< DebugOnlyOpt, true, cl::parser< std::string > >, CreateDebugOnly > DebugOnly
Definition: Debug.cpp:187
static DebugOnlyOpt DebugOnlyOptLoc
Definition: Debug.cpp:165
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:85
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:710
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:581
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:590
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:301
static constexpr size_t npos
Definition: StringRef.h:57
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
circular_raw_ostream - A raw_ostream which can save its data to a circular buffer,...
void flushBufferWithBanner()
flushBufferWithBanner - Force output of the buffer along with a small header.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
@ ValueRequired
Definition: CommandLine.h:132
template class LLVM_TEMPLATE_ABI opt< unsigned >
Definition: CommandLine.cpp:82
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:464
LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie)
Add a function to be called when an abort/kill signal is delivered to the process.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI bool EnableDebugBuffering
EnableDebugBuffering - This defaults to false.
Definition: Debug.cpp:240
LLVM_ABI bool isCurrentDebugType(const char *Type, int Level=0)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...
Definition: Debug.cpp:81
void initDebugOptions()
Definition: Debug.cpp:189
LLVM_ABI bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
Definition: Debug.cpp:68
LLVM_ABI void setCurrentDebugTypes(const char **Types, unsigned Count)
setCurrentDebugTypes - Set the current debug type, as if the -debug-only=X,Y,Z option were specified.
Definition: Debug.cpp:111
static ManagedStatic< std::vector< std::pair< std::string, std::optional< int > > > > CurrentDebugType
The current debug type and an optional debug level.
Definition: Debug.cpp:76
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI void setCurrentDebugType(const char *Type)
setCurrentDebugType - Set the current debug type, as if the -debug-only=X option were specified.
Definition: Debug.cpp:107
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.