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