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