From: rousskov <> Date: Wed, 27 Feb 2008 01:43:30 +0000 (+0000) Subject: Bug #2224 fix: reentrant debugging crashes Squid X-Git-Tag: BASIC_TPROXY4~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9eab365dad7aa94bc545812349f5bccc67ae97a2;p=thirdparty%2Fsquid.git Bug #2224 fix: reentrant debugging crashes Squid Reentrant debugging occurs when something being written into the debugging stream produces its own debugging. For example, a field accessor method may make cbdata-validation calls, which would produce debugging. Logging such field would crash Squid if sufficiently high debugging level is enabled. With this change, the Debug methods detect reentrant calls and mostly ignore them, allowing the caller to append debugging information to the existing debug stream. A short debugging label is added before and after the reentrant debugging message to reduce confusion that overlapping debugging statements may cause during log analysis. --- diff --git a/src/Debug.h b/src/Debug.h index 3c01c6e11b..daab471560 100644 --- a/src/Debug.h +++ b/src/Debug.h @@ -1,5 +1,5 @@ /* - * $Id: Debug.h,v 1.12 2008/01/11 05:04:02 amosjeffries Exp $ + * $Id: Debug.h,v 1.13 2008/02/26 18:43:30 rousskov Exp $ * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived @@ -69,7 +69,11 @@ public: static void parseOptions(char const *); private: + // Hack: replaces global ::xassert() to debug debugging assertions + static void xassert(const char *msg, const char *file, int line); + static std::ostringstream *CurrentDebug; + static int TheDepth; // level of nested debugging calls }; /* Debug stream */ diff --git a/src/debug.cc b/src/debug.cc index 3e8a4b72ed..cfe2ebc63a 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1,5 +1,5 @@ /* - * $Id: debug.cc,v 1.108 2007/12/29 18:20:22 hno Exp $ + * $Id: debug.cc,v 1.109 2008/02/26 18:43:30 rousskov Exp $ * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived @@ -735,21 +735,50 @@ ctx_get_descr(Ctx ctx) { return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : ""; } +int Debug::TheDepth = 0; + std::ostream & Debug::getDebugOut() { - assert (CurrentDebug == NULL); - CurrentDebug = new std::ostringstream(); - // set default formatting flags - CurrentDebug->setf(std::ios::fixed); - CurrentDebug->precision(2); + assert(TheDepth >= 0); + ++TheDepth; + if (TheDepth > 1) { + assert(CurrentDebug); + *CurrentDebug << std::endl << "reentrant debuging " << TheDepth << "-{"; + } else { + assert(!CurrentDebug); + CurrentDebug = new std::ostringstream(); + // set default formatting flags + CurrentDebug->setf(std::ios::fixed); + CurrentDebug->precision(2); + } return *CurrentDebug; } void Debug::finishDebug() { - _db_print("%s\n", CurrentDebug->str().c_str()); - delete CurrentDebug; - CurrentDebug = NULL; + assert(TheDepth >= 0); + assert(CurrentDebug); + if (TheDepth > 1) { + *CurrentDebug << "}-" << TheDepth << std::endl; + } else { + assert(TheDepth == 1); + _db_print("%s\n", CurrentDebug->str().c_str()); + delete CurrentDebug; + CurrentDebug = NULL; + } + --TheDepth; +} + +// Hack: replaces global ::xassert() to debug debugging assertions +// Relies on assert macro calling xassert() without a specific scope. +void +Debug::xassert(const char *msg, const char *file, int line) { + + if (CurrentDebug) { + *CurrentDebug << "assertion failed: " << file << ":" << line << + ": \"" << msg << "\""; + } + abort(); } std::ostringstream (*Debug::CurrentDebug)(NULL);