Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 1 | //===-- Debug.cpp - An easy way to add debug output to your code ----------===// |
Misha Brukman | 10468d8 | 2005-04-21 22:55:34 +0000 | [diff] [blame] | 2 | // |
John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Misha Brukman | 10468d8 | 2005-04-21 22:55:34 +0000 | [diff] [blame] | 7 | // |
John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 9 | // |
Chad Rosier | 7c427c4 | 2012-07-26 20:38:52 +0000 | [diff] [blame] | 10 | // This file implements a handy way of adding debugging information to your |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 11 | // code, without it being enabled all of the time, and without having to add |
| 12 | // command line options to enable it. |
| 13 | // |
| 14 | // In particular, just wrap your code with the DEBUG() macro, and it will be |
| 15 | // enabled automatically if you specify '-debug' on the command-line. |
| 16 | // Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify |
| 17 | // that your debug code belongs to class "foo". Then, on the command line, you |
| 18 | // can specify '-debug-only=foo' to enable JUST the debug information for the |
| 19 | // foo class. |
| 20 | // |
Chad Rosier | 7c427c4 | 2012-07-26 20:38:52 +0000 | [diff] [blame] | 21 | // When compiling without assertions, the -debug-* options and all code in |
Chad Rosier | bd9f2ba | 2012-07-27 21:41:59 +0000 | [diff] [blame] | 22 | // DEBUG() statements disappears, so it does not affect the runtime of the code. |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 23 | // |
| 24 | //===----------------------------------------------------------------------===// |
| 25 | |
Bill Wendling | 9594f3a | 2006-11-17 09:54:47 +0000 | [diff] [blame] | 26 | #include "llvm/Support/Debug.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 27 | #include "llvm/Support/CommandLine.h" |
Chandler Carruth | d990388 | 2015-01-14 11:23:27 +0000 | [diff] [blame] | 28 | #include "llvm/Support/ManagedStatic.h" |
Michael J. Spencer | 447762d | 2010-11-29 18:16:10 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Signals.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 30 | #include "llvm/Support/circular_raw_ostream.h" |
Benjamin Kramer | 799003b | 2015-03-23 19:32:43 +0000 | [diff] [blame] | 31 | #include "llvm/Support/raw_ostream.h" |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 32 | |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 33 | #undef isCurrentDebugType |
| 34 | #undef setCurrentDebugType |
Eugene Leviant | 687d402 | 2016-12-27 10:24:58 +0000 | [diff] [blame] | 35 | #undef setCurrentDebugTypes |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 36 | |
Chris Lattner | c9499b6 | 2003-12-14 21:35:53 +0000 | [diff] [blame] | 37 | using namespace llvm; |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 38 | |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 39 | // Even though LLVM might be built with NDEBUG, define symbols that the code |
| 40 | // built without NDEBUG can depend on via the llvm/Support/Debug.h header. |
| 41 | namespace llvm { |
| 42 | /// Exported boolean set by the -debug option. |
| 43 | bool DebugFlag = false; |
| 44 | |
| 45 | static ManagedStatic<std::vector<std::string>> CurrentDebugType; |
| 46 | |
| 47 | /// Return true if the specified string is the debug type |
| 48 | /// specified on the command line, or if none was specified on the command line |
| 49 | /// with the -debug-only=X option. |
| 50 | bool isCurrentDebugType(const char *DebugType) { |
| 51 | if (CurrentDebugType->empty()) |
| 52 | return true; |
Yaron Keren | 90811cb | 2015-05-27 18:11:07 +0000 | [diff] [blame] | 53 | // See if DebugType is in list. Note: do not use find() as that forces us to |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 54 | // unnecessarily create an std::string instance. |
Yaron Keren | 90811cb | 2015-05-27 18:11:07 +0000 | [diff] [blame] | 55 | for (auto &d : *CurrentDebugType) { |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 56 | if (d == DebugType) |
| 57 | return true; |
| 58 | } |
| 59 | return false; |
| 60 | } |
| 61 | |
| 62 | /// Set the current debug type, as if the -debug-only=X |
| 63 | /// option were specified. Note that DebugFlag also needs to be set to true for |
| 64 | /// debug output to be produced. |
| 65 | /// |
Eugene Leviant | 687d402 | 2016-12-27 10:24:58 +0000 | [diff] [blame] | 66 | void setCurrentDebugTypes(const char **Types, unsigned Count); |
| 67 | |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 68 | void setCurrentDebugType(const char *Type) { |
Eugene Leviant | c089e40 | 2016-12-27 09:31:20 +0000 | [diff] [blame] | 69 | setCurrentDebugTypes(&Type, 1); |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 70 | } |
| 71 | |
Eugene Leviant | c089e40 | 2016-12-27 09:31:20 +0000 | [diff] [blame] | 72 | void setCurrentDebugTypes(const char **Types, unsigned Count) { |
| 73 | CurrentDebugType->clear(); |
| 74 | for (size_t T = 0; T < Count; ++T) |
| 75 | CurrentDebugType->push_back(Types[T]); |
| 76 | } |
Dmitri Gribenko | 3e1551c | 2015-02-19 05:30:16 +0000 | [diff] [blame] | 77 | } // namespace llvm |
| 78 | |
Daniel Dunbar | 34ee203 | 2009-08-23 08:50:52 +0000 | [diff] [blame] | 79 | // All Debug.h functionality is a no-op in NDEBUG mode. |
| 80 | #ifndef NDEBUG |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 81 | |
Chris Lattner | 7e3cfe3 | 2009-08-23 07:05:39 +0000 | [diff] [blame] | 82 | // -debug - Command line option to enable the DEBUG statements in the passes. |
| 83 | // This flag may only be enabled in debug builds. |
| 84 | static cl::opt<bool, true> |
| 85 | Debug("debug", cl::desc("Enable debug output"), cl::Hidden, |
| 86 | cl::location(DebugFlag)); |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 87 | |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 88 | // -debug-buffer-size - Buffer the last N characters of debug output |
| 89 | //until program termination. |
| 90 | static cl::opt<unsigned> |
| 91 | DebugBufferSize("debug-buffer-size", |
Erik Verbruggen | ef40cdd | 2013-02-20 22:33:46 +0000 | [diff] [blame] | 92 | cl::desc("Buffer the last N characters of debug output " |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 93 | "until program termination. " |
| 94 | "[default 0 -- immediate print-out]"), |
| 95 | cl::Hidden, |
| 96 | cl::init(0)); |
| 97 | |
Dan Gohman | b29cda9 | 2010-04-15 17:08:50 +0000 | [diff] [blame] | 98 | namespace { |
| 99 | |
| 100 | struct DebugOnlyOpt { |
Chris Lattner | 7e3cfe3 | 2009-08-23 07:05:39 +0000 | [diff] [blame] | 101 | void operator=(const std::string &Val) const { |
Matthias Braun | 87a3ba6 | 2014-11-21 18:06:09 +0000 | [diff] [blame] | 102 | if (Val.empty()) |
| 103 | return; |
| 104 | DebugFlag = true; |
Christof Douma | f617e67 | 2016-01-12 10:23:13 +0000 | [diff] [blame] | 105 | SmallVector<StringRef,8> dbgTypes; |
| 106 | StringRef(Val).split(dbgTypes, ',', -1, false); |
| 107 | for (auto dbgType : dbgTypes) |
| 108 | CurrentDebugType->push_back(dbgType); |
Chris Lattner | 7e3cfe3 | 2009-08-23 07:05:39 +0000 | [diff] [blame] | 109 | } |
Dan Gohman | b29cda9 | 2010-04-15 17:08:50 +0000 | [diff] [blame] | 110 | }; |
| 111 | |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 112 | } |
Dan Gohman | b29cda9 | 2010-04-15 17:08:50 +0000 | [diff] [blame] | 113 | |
| 114 | static DebugOnlyOpt DebugOnlyOptLoc; |
Chris Lattner | 8fb754a | 2003-08-01 22:15:41 +0000 | [diff] [blame] | 115 | |
Chris Lattner | 7e3cfe3 | 2009-08-23 07:05:39 +0000 | [diff] [blame] | 116 | static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> > |
Christof Douma | f617e67 | 2016-01-12 10:23:13 +0000 | [diff] [blame] | 117 | DebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"), |
Matthias Braun | 87a3ba6 | 2014-11-21 18:06:09 +0000 | [diff] [blame] | 118 | cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"), |
Chris Lattner | 7e3cfe3 | 2009-08-23 07:05:39 +0000 | [diff] [blame] | 119 | cl::location(DebugOnlyOptLoc), cl::ValueRequired); |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 120 | // Signal handlers - dump debug output on termination. |
Dan Gohman | b452d4e | 2010-03-24 19:38:02 +0000 | [diff] [blame] | 121 | static void debug_user_sig_handler(void *Cookie) { |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 122 | // This is a bit sneaky. Since this is under #ifndef NDEBUG, we |
| 123 | // know that debug mode is enabled and dbgs() really is a |
| 124 | // circular_raw_ostream. If NDEBUG is defined, then dbgs() == |
| 125 | // errs() but this will never be invoked. |
Rafael Espindola | 62e6ec0 | 2015-04-09 16:59:07 +0000 | [diff] [blame] | 126 | llvm::circular_raw_ostream &dbgout = |
| 127 | static_cast<circular_raw_ostream &>(llvm::dbgs()); |
| 128 | dbgout.flushBufferWithBanner(); |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 129 | } |
| 130 | |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 131 | /// dbgs - Return a circular-buffered debug stream. |
| 132 | raw_ostream &llvm::dbgs() { |
| 133 | // Do one-time initialization in a thread-safe way. |
| 134 | static struct dbgstream { |
| 135 | circular_raw_ostream strm; |
| 136 | |
| 137 | dbgstream() : |
| 138 | strm(errs(), "*** Debug Log Output ***\n", |
| 139 | (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) { |
| 140 | if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0) |
| 141 | // TODO: Add a handler for SIGUSER1-type signals so the user can |
| 142 | // force a debug dump. |
Craig Topper | 2617dcc | 2014-04-15 06:32:26 +0000 | [diff] [blame] | 143 | sys::AddSignalHandler(&debug_user_sig_handler, nullptr); |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 144 | // Otherwise we've already set the debug stream buffer size to |
David Greene | b760d0c | 2009-12-23 23:23:15 +0000 | [diff] [blame] | 145 | // zero, disabling buffering so it will output directly to errs(). |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 146 | } |
| 147 | } thestrm; |
| 148 | |
| 149 | return thestrm.strm; |
| 150 | } |
| 151 | |
Daniel Dunbar | 34ee203 | 2009-08-23 08:50:52 +0000 | [diff] [blame] | 152 | #else |
| 153 | // Avoid "has no symbols" warning. |
Chris Lattner | fbaac77 | 2009-10-28 15:32:19 +0000 | [diff] [blame] | 154 | namespace llvm { |
David Greene | 35dca86 | 2010-01-20 15:27:19 +0000 | [diff] [blame] | 155 | /// dbgs - Return errs(). |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 156 | raw_ostream &dbgs() { |
David Greene | 35dca86 | 2010-01-20 15:27:19 +0000 | [diff] [blame] | 157 | return errs(); |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 158 | } |
Chris Lattner | fbaac77 | 2009-10-28 15:32:19 +0000 | [diff] [blame] | 159 | } |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 160 | |
Daniel Dunbar | 34ee203 | 2009-08-23 08:50:52 +0000 | [diff] [blame] | 161 | #endif |
David Greene | 64506db | 2009-12-23 16:39:06 +0000 | [diff] [blame] | 162 | |
| 163 | /// EnableDebugBuffering - Turn on signal handler installation. |
| 164 | /// |
| 165 | bool llvm::EnableDebugBuffering = false; |