Home | History | Annotate | Download | only in Support
      1 //===-- Debug.cpp - An easy way to add debug output to your code ----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements a handy way of adding debugging information to your
     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 //
     21 // When compiling without assertions, the -debug-* options and all code in
     22 // DEBUG() statements disappears, so it does not affect the runtime of the 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 #undef isCurrentDebugType
     34 #undef setCurrentDebugType
     35 
     36 using namespace llvm;
     37 
     38 // Even though LLVM might be built with NDEBUG, define symbols that the code
     39 // built without NDEBUG can depend on via the llvm/Support/Debug.h header.
     40 namespace llvm {
     41 /// Exported boolean set by the -debug option.
     42 bool DebugFlag = false;
     43 
     44 static ManagedStatic<std::vector<std::string>> CurrentDebugType;
     45 
     46 /// Return true if the specified string is the debug type
     47 /// specified on the command line, or if none was specified on the command line
     48 /// with the -debug-only=X option.
     49 bool isCurrentDebugType(const char *DebugType) {
     50   if (CurrentDebugType->empty())
     51     return true;
     52   // See if DebugType is in list. Note: do not use find() as that forces us to
     53   // unnecessarily create an std::string instance.
     54   for (auto &d : *CurrentDebugType) {
     55     if (d == DebugType)
     56       return true;
     57   }
     58   return false;
     59 }
     60 
     61 /// Set the current debug type, as if the -debug-only=X
     62 /// option were specified.  Note that DebugFlag also needs to be set to true for
     63 /// debug output to be produced.
     64 ///
     65 void setCurrentDebugType(const char *Type) {
     66   CurrentDebugType->clear();
     67   CurrentDebugType->push_back(Type);
     68 }
     69 
     70 } // namespace llvm
     71 
     72 // All Debug.h functionality is a no-op in NDEBUG mode.
     73 #ifndef NDEBUG
     74 
     75 // -debug - Command line option to enable the DEBUG statements in the passes.
     76 // This flag may only be enabled in debug builds.
     77 static cl::opt<bool, true>
     78 Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
     79       cl::location(DebugFlag));
     80 
     81 // -debug-buffer-size - Buffer the last N characters of debug output
     82 //until program termination.
     83 static cl::opt<unsigned>
     84 DebugBufferSize("debug-buffer-size",
     85                 cl::desc("Buffer the last N characters of debug output "
     86                          "until program termination. "
     87                          "[default 0 -- immediate print-out]"),
     88                 cl::Hidden,
     89                 cl::init(0));
     90 
     91 namespace {
     92 
     93 struct DebugOnlyOpt {
     94   void operator=(const std::string &Val) const {
     95     if (Val.empty())
     96       return;
     97     DebugFlag = true;
     98     SmallVector<StringRef,8> dbgTypes;
     99     StringRef(Val).split(dbgTypes, ',', -1, false);
    100     for (auto dbgType : dbgTypes)
    101       CurrentDebugType->push_back(dbgType);
    102   }
    103 };
    104 
    105 }
    106 
    107 static DebugOnlyOpt DebugOnlyOptLoc;
    108 
    109 static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
    110 DebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"),
    111           cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
    112           cl::location(DebugOnlyOptLoc), cl::ValueRequired);
    113 // Signal handlers - dump debug output on termination.
    114 static void debug_user_sig_handler(void *Cookie) {
    115   // This is a bit sneaky.  Since this is under #ifndef NDEBUG, we
    116   // know that debug mode is enabled and dbgs() really is a
    117   // circular_raw_ostream.  If NDEBUG is defined, then dbgs() ==
    118   // errs() but this will never be invoked.
    119   llvm::circular_raw_ostream &dbgout =
    120       static_cast<circular_raw_ostream &>(llvm::dbgs());
    121   dbgout.flushBufferWithBanner();
    122 }
    123 
    124 /// dbgs - Return a circular-buffered debug stream.
    125 raw_ostream &llvm::dbgs() {
    126   // Do one-time initialization in a thread-safe way.
    127   static struct dbgstream {
    128     circular_raw_ostream strm;
    129 
    130     dbgstream() :
    131         strm(errs(), "*** Debug Log Output ***\n",
    132              (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) {
    133       if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0)
    134         // TODO: Add a handler for SIGUSER1-type signals so the user can
    135         // force a debug dump.
    136         sys::AddSignalHandler(&debug_user_sig_handler, nullptr);
    137       // Otherwise we've already set the debug stream buffer size to
    138       // zero, disabling buffering so it will output directly to errs().
    139     }
    140   } thestrm;
    141 
    142   return thestrm.strm;
    143 }
    144 
    145 #else
    146 // Avoid "has no symbols" warning.
    147 namespace llvm {
    148   /// dbgs - Return errs().
    149   raw_ostream &dbgs() {
    150     return errs();
    151   }
    152 }
    153 
    154 #endif
    155 
    156 /// EnableDebugBuffering - Turn on signal handler installation.
    157 ///
    158 bool llvm::EnableDebugBuffering = false;
    159