diff options
author | David Greene <greened@obbligato.org> | 2009-12-23 16:39:06 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2009-12-23 16:39:06 +0000 |
commit | b5d568cc70506c4cb3aa7abc3370d3ac9411b4a0 (patch) | |
tree | c1d4cee8a7c672a89209661aca67e62e9c67ac34 /lib/Support | |
parent | e59011e7d913b59dd244b0295a984dcfe7976e72 (diff) | |
download | external_llvm-b5d568cc70506c4cb3aa7abc3370d3ac9411b4a0.zip external_llvm-b5d568cc70506c4cb3aa7abc3370d3ac9411b4a0.tar.gz external_llvm-b5d568cc70506c4cb3aa7abc3370d3ac9411b4a0.tar.bz2 |
Provide dbgs(), a circular-buffering debug output stream. By default it
simply passes output to errs(). If -debug-buffer-size=N is set N > 0,
dbgs() buffers its output until program termination and dumps the last N
characters sent to it. This is handy when debugging very large inputs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-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 50abe01..12b38c7 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. + } + } 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; |