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" |
27 | #include "llvm/Support/CommandLine.h" |
28 | #include "llvm/Support/ManagedStatic.h" |
29 | #include "llvm/Support/Signals.h" |
30 | #include "llvm/Support/circular_raw_ostream.h" |
31 | #include "llvm/Support/raw_ostream.h" |
32 | |
33 | #include "DebugOptions.h" |
34 | |
35 | #undef isCurrentDebugType |
36 | #undef setCurrentDebugType |
37 | #undef setCurrentDebugTypes |
38 | |
39 | using namespace llvm; |
40 | |
41 | // Even though LLVM might be built with NDEBUG, define symbols that the code |
42 | // built without NDEBUG can depend on via the llvm/Support/Debug.h header. |
43 | namespace llvm { |
44 | /// Exported boolean set by the -debug option. |
45 | bool DebugFlag = false; |
46 | |
47 | static ManagedStatic<std::vector<std::string>> CurrentDebugType; |
48 | |
49 | /// Return true if the specified string is the debug type |
50 | /// specified on the command line, or if none was specified on the command line |
51 | /// with the -debug-only=X option. |
52 | bool isCurrentDebugType(const char *DebugType) { |
53 | if (CurrentDebugType->empty()) |
54 | return true; |
55 | // See if DebugType is in list. Note: do not use find() as that forces us to |
56 | // unnecessarily create an std::string instance. |
57 | for (auto &d : *CurrentDebugType) { |
58 | if (d == DebugType) |
59 | return true; |
60 | } |
61 | return false; |
62 | } |
63 | |
64 | /// Set the current debug type, as if the -debug-only=X |
65 | /// option were specified. Note that DebugFlag also needs to be set to true for |
66 | /// debug output to be produced. |
67 | /// |
68 | void setCurrentDebugTypes(const char **Types, unsigned Count); |
69 | |
70 | void setCurrentDebugType(const char *Type) { |
71 | setCurrentDebugTypes(Types: &Type, Count: 1); |
72 | } |
73 | |
74 | void setCurrentDebugTypes(const char **Types, unsigned Count) { |
75 | CurrentDebugType->clear(); |
76 | llvm::append_range(C&: *CurrentDebugType, R: ArrayRef(Types, Count)); |
77 | } |
78 | } // namespace llvm |
79 | |
80 | // All Debug.h functionality is a no-op in NDEBUG mode. |
81 | #ifndef NDEBUG |
82 | |
83 | namespace { |
84 | struct CreateDebug { |
85 | static void *call() { |
86 | return new cl::opt<bool, true>("debug" , cl::desc("Enable debug output" ), |
87 | cl::Hidden, cl::location(DebugFlag)); |
88 | } |
89 | }; |
90 | |
91 | // -debug-buffer-size - Buffer the last N characters of debug output |
92 | //until program termination. |
93 | struct CreateDebugBufferSize { |
94 | static void *call() { |
95 | return new cl::opt<unsigned>( |
96 | "debug-buffer-size" , |
97 | cl::desc("Buffer the last N characters of debug output " |
98 | "until program termination. " |
99 | "[default 0 -- immediate print-out]" ), |
100 | cl::Hidden, cl::init(0)); |
101 | } |
102 | }; |
103 | } // namespace |
104 | |
105 | // -debug - Command line option to enable the DEBUG statements in the passes. |
106 | // This flag may only be enabled in debug builds. |
107 | static ManagedStatic<cl::opt<bool, true>, CreateDebug> Debug; |
108 | static ManagedStatic<cl::opt<unsigned>, CreateDebugBufferSize> DebugBufferSize; |
109 | |
110 | namespace { |
111 | |
112 | struct DebugOnlyOpt { |
113 | void operator=(const std::string &Val) const { |
114 | if (Val.empty()) |
115 | return; |
116 | DebugFlag = true; |
117 | SmallVector<StringRef,8> dbgTypes; |
118 | StringRef(Val).split(dbgTypes, ',', -1, false); |
119 | for (auto dbgType : dbgTypes) |
120 | CurrentDebugType->push_back(std::string(dbgType)); |
121 | } |
122 | }; |
123 | } // namespace |
124 | |
125 | static DebugOnlyOpt DebugOnlyOptLoc; |
126 | |
127 | namespace { |
128 | struct CreateDebugOnly { |
129 | static void *call() { |
130 | return new cl::opt<DebugOnlyOpt, true, cl::parser<std::string>>( |
131 | "debug-only" , |
132 | cl::desc("Enable a specific type of debug output (comma separated list " |
133 | "of types)" ), |
134 | cl::Hidden, cl::value_desc("debug string" ), |
135 | cl::location(DebugOnlyOptLoc), cl::ValueRequired); |
136 | } |
137 | }; |
138 | } // namespace |
139 | |
140 | static ManagedStatic<cl::opt<DebugOnlyOpt, true, cl::parser<std::string>>, |
141 | CreateDebugOnly> |
142 | DebugOnly; |
143 | |
144 | void llvm::initDebugOptions() { |
145 | *Debug; |
146 | *DebugBufferSize; |
147 | *DebugOnly; |
148 | } |
149 | |
150 | // Signal handlers - dump debug output on termination. |
151 | static void debug_user_sig_handler(void *Cookie) { |
152 | // This is a bit sneaky. Since this is under #ifndef NDEBUG, we |
153 | // know that debug mode is enabled and dbgs() really is a |
154 | // circular_raw_ostream. If NDEBUG is defined, then dbgs() == |
155 | // errs() but this will never be invoked. |
156 | llvm::circular_raw_ostream &dbgout = |
157 | static_cast<circular_raw_ostream &>(llvm::dbgs()); |
158 | dbgout.flushBufferWithBanner(); |
159 | } |
160 | |
161 | /// dbgs - Return a circular-buffered debug stream. |
162 | raw_ostream &llvm::dbgs() { |
163 | // Do one-time initialization in a thread-safe way. |
164 | static struct dbgstream { |
165 | circular_raw_ostream strm; |
166 | |
167 | dbgstream() |
168 | : strm(errs(), "*** Debug Log Output ***\n" , |
169 | (!EnableDebugBuffering || !DebugFlag) ? 0 : *DebugBufferSize) { |
170 | if (EnableDebugBuffering && DebugFlag && *DebugBufferSize != 0) |
171 | // TODO: Add a handler for SIGUSER1-type signals so the user can |
172 | // force a debug dump. |
173 | sys::AddSignalHandler(&debug_user_sig_handler, nullptr); |
174 | // Otherwise we've already set the debug stream buffer size to |
175 | // zero, disabling buffering so it will output directly to errs(). |
176 | } |
177 | } thestrm; |
178 | |
179 | return thestrm.strm; |
180 | } |
181 | |
182 | #else |
183 | // Avoid "has no symbols" warning. |
184 | namespace llvm { |
185 | /// dbgs - Return errs(). |
186 | raw_ostream &dbgs() { |
187 | return errs(); |
188 | } |
189 | } |
190 | void llvm::initDebugOptions() {} |
191 | #endif |
192 | |
193 | /// EnableDebugBuffering - Turn on signal handler installation. |
194 | /// |
195 | bool llvm::EnableDebugBuffering = false; |
196 | |