diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 | 
| commit | 1e7804dbd25b8dbf534c850355d70ad215206f4b (patch) | |
| tree | dba00119388b84f9f44e6ec5e9129f807fd79ca3 /lib/Support/Debug.cpp | |
| parent | 571945e6affd20b19264ec22495da418d0fbdbb4 (diff) | |
Notes
Diffstat (limited to 'lib/Support/Debug.cpp')
| -rw-r--r-- | lib/Support/Debug.cpp | 56 | 
1 files changed, 55 insertions, 1 deletions
| diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp index 50abe0164ac2..a03577101bad 100644 --- a/lib/Support/Debug.cpp +++ b/lib/Support/Debug.cpp @@ -25,6 +25,9 @@  #include "llvm/Support/CommandLine.h"  #include "llvm/Support/Debug.h" +#include "llvm/Support/circular_raw_ostream.h" +#include "llvm/System/Signals.h" +  using namespace llvm;  // All Debug.h functionality is a no-op in NDEBUG mode. @@ -37,6 +40,16 @@ static cl::opt<bool, true>  Debug("debug", cl::desc("Enable debug output"), cl::Hidden,        cl::location(DebugFlag)); +// -debug-buffer-size - Buffer the last N characters of debug output +//until program termination. +static cl::opt<unsigned> +DebugBufferSize("debug-buffer-size", +                cl::desc("Buffer the last N characters of debug output" +                         "until program termination. " +                         "[default 0 -- immediate print-out]"), +                cl::Hidden, +                cl::init(0)); +  static std::string CurrentDebugType;  static struct DebugOnlyOpt {    void operator=(const std::string &Val) const { @@ -50,6 +63,18 @@ DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"),            cl::Hidden, cl::value_desc("debug string"),            cl::location(DebugOnlyOptLoc), cl::ValueRequired); +// Signal handlers - dump debug output on termination. +static void debug_user_sig_handler(void *Cookie) +{ +  // This is a bit sneaky.  Since this is under #ifndef NDEBUG, we +  // know that debug mode is enabled and dbgs() really is a +  // circular_raw_ostream.  If NDEBUG is defined, then dbgs() == +  // errs() but this will never be invoked. +  llvm::circular_raw_ostream *dbgout = +    static_cast<llvm::circular_raw_ostream *>(&llvm::dbgs()); +  dbgout->flushBufferWithBanner(); +} +  // isCurrentDebugType - Return true if the specified string is the debug type  // specified on the command line, or if none was specified on the command line  // with the -debug-only=X option. @@ -66,9 +91,38 @@ void llvm::SetCurrentDebugType(const char *Type) {    CurrentDebugType = Type;  } +/// dbgs - Return a circular-buffered debug stream. +raw_ostream &llvm::dbgs() { +  // Do one-time initialization in a thread-safe way. +  static struct dbgstream { +    circular_raw_ostream strm; + +    dbgstream() : +        strm(errs(), "*** Debug Log Output ***\n", +             (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) { +      if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0) +        // TODO: Add a handler for SIGUSER1-type signals so the user can +        // force a debug dump. +        sys::AddSignalHandler(&debug_user_sig_handler, 0); +      // Otherwise we've already set the debug stream buffer size to +      // zero, disabling buffering so it will output directly to errs(). +    } +  } thestrm; + +  return thestrm.strm; +} +  #else  // Avoid "has no symbols" warning.  namespace llvm { -int Debug_dummy = 0; +  /// dbgs - Return dbgs(). +  raw_ostream &dbgs() { +    return dbgs(); +  }  } +  #endif + +/// EnableDebugBuffering - Turn on signal handler installation. +/// +bool llvm::EnableDebugBuffering = false; | 
