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 | for (size_t T = 0; T < Count; ++T) |
77 | CurrentDebugType->push_back(x: Types[T]); |
78 | } |
79 | } // namespace llvm |
80 | |
81 | // All Debug.h functionality is a no-op in NDEBUG mode. |
82 | #ifndef NDEBUG |
83 | |
84 | namespace { |
85 | struct CreateDebug { |
86 | static void *call() { |
87 | return new cl::opt<bool, true>("debug" , cl::desc("Enable debug output" ), |
88 | cl::Hidden, cl::location(DebugFlag)); |
89 | } |
90 | }; |
91 | |
92 | // -debug-buffer-size - Buffer the last N characters of debug output |
93 | //until program termination. |
94 | struct CreateDebugBufferSize { |
95 | static void *call() { |
96 | return new cl::opt<unsigned>( |
97 | "debug-buffer-size" , |
98 | cl::desc("Buffer the last N characters of debug output " |
99 | "until program termination. " |
100 | "[default 0 -- immediate print-out]" ), |
101 | cl::Hidden, cl::init(0)); |
102 | } |
103 | }; |
104 | } // namespace |
105 | |
106 | // -debug - Command line option to enable the DEBUG statements in the passes. |
107 | // This flag may only be enabled in debug builds. |
108 | static ManagedStatic<cl::opt<bool, true>, CreateDebug> Debug; |
109 | static ManagedStatic<cl::opt<unsigned>, CreateDebugBufferSize> DebugBufferSize; |
110 | |
111 | namespace { |
112 | |
113 | struct DebugOnlyOpt { |
114 | void operator=(const std::string &Val) const { |
115 | if (Val.empty()) |
116 | return; |
117 | DebugFlag = true; |
118 | SmallVector<StringRef,8> dbgTypes; |
119 | StringRef(Val).split(dbgTypes, ',', -1, false); |
120 | for (auto dbgType : dbgTypes) |
121 | CurrentDebugType->push_back(std::string(dbgType)); |
122 | } |
123 | }; |
124 | } // namespace |
125 | |
126 | static DebugOnlyOpt DebugOnlyOptLoc; |
127 | |
128 | namespace { |
129 | struct CreateDebugOnly { |
130 | static void *call() { |
131 | return new cl::opt<DebugOnlyOpt, true, cl::parser<std::string>>( |
132 | "debug-only" , |
133 | cl::desc("Enable a specific type of debug output (comma separated list " |
134 | "of types)" ), |
135 | cl::Hidden, cl::value_desc("debug string" ), |
136 | cl::location(DebugOnlyOptLoc), cl::ValueRequired); |
137 | } |
138 | }; |
139 | } // namespace |
140 | |
141 | static ManagedStatic<cl::opt<DebugOnlyOpt, true, cl::parser<std::string>>, |
142 | CreateDebugOnly> |
143 | DebugOnly; |
144 | |
145 | void llvm::initDebugOptions() { |
146 | *Debug; |
147 | *DebugBufferSize; |
148 | *DebugOnly; |
149 | } |
150 | |
151 | // Signal handlers - dump debug output on termination. |
152 | static void debug_user_sig_handler(void *Cookie) { |
153 | // This is a bit sneaky. Since this is under #ifndef NDEBUG, we |
154 | // know that debug mode is enabled and dbgs() really is a |
155 | // circular_raw_ostream. If NDEBUG is defined, then dbgs() == |
156 | // errs() but this will never be invoked. |
157 | llvm::circular_raw_ostream &dbgout = |
158 | static_cast<circular_raw_ostream &>(llvm::dbgs()); |
159 | dbgout.flushBufferWithBanner(); |
160 | } |
161 | |
162 | /// dbgs - Return a circular-buffered debug stream. |
163 | raw_ostream &llvm::dbgs() { |
164 | // Do one-time initialization in a thread-safe way. |
165 | static struct dbgstream { |
166 | circular_raw_ostream strm; |
167 | |
168 | dbgstream() |
169 | : strm(errs(), "*** Debug Log Output ***\n" , |
170 | (!EnableDebugBuffering || !DebugFlag) ? 0 : *DebugBufferSize) { |
171 | if (EnableDebugBuffering && DebugFlag && *DebugBufferSize != 0) |
172 | // TODO: Add a handler for SIGUSER1-type signals so the user can |
173 | // force a debug dump. |
174 | sys::AddSignalHandler(&debug_user_sig_handler, nullptr); |
175 | // Otherwise we've already set the debug stream buffer size to |
176 | // zero, disabling buffering so it will output directly to errs(). |
177 | } |
178 | } thestrm; |
179 | |
180 | return thestrm.strm; |
181 | } |
182 | |
183 | #else |
184 | // Avoid "has no symbols" warning. |
185 | namespace llvm { |
186 | /// dbgs - Return errs(). |
187 | raw_ostream &dbgs() { |
188 | return errs(); |
189 | } |
190 | } |
191 | void llvm::initDebugOptions() {} |
192 | #endif |
193 | |
194 | /// EnableDebugBuffering - Turn on signal handler installation. |
195 | /// |
196 | bool llvm::EnableDebugBuffering = false; |
197 | |