# # patch "ChangeLog" # from [76f343c8a869b97658a44ff3470f08879cc74664] # to [9e93c46aea901735b1fe7d8496e21b7091ca840a] # # patch "Makefile.am" # from [a6c031cdb289e4294a118c97105a04e75fdebcb0] # to [a7e491111a9b40a5275427ec6fab1c85911bce2e] # # patch "sanity.cc" # from [2a3933f0a61318d32c1f2061fcadd106761fce87] # to [2396edeaed987d915d9ad8665d1c3e24534043b6] # # patch "sanity.hh" # from [2fea4a99d4e7e8b108c8168d974243c6fcb3212a] # to [c7fe8c720645f18d069058004cc1c3dd9db3f00a] # =============================================== --- ChangeLog 76f343c8a869b97658a44ff3470f08879cc74664 +++ ChangeLog 9e93c46aea901735b1fe7d8496e21b7091ca840a @@ -1,3 +1,11 @@ +2005-07-24 Nathaniel Smith + + * sanity.{hh,cc} (sanity, dump_buffer, invariant_failure) + (index_failure, MusingI, Musing, M): Implement macro M(), for + 'musing', which marks data that monotone was musing over when an + invariant tripped. + * Makefile.am (MOST_SOURCES): Fix spacing. + 2005-07-23 Nathaniel Smith * ui.{hh,cc} (guess_terminal_width): New function. =============================================== --- Makefile.am a6c031cdb289e4294a118c97105a04e75fdebcb0 +++ Makefile.am a7e491111a9b40a5275427ec6fab1c85911bce2e @@ -40,7 +40,7 @@ selectors.cc selectors.hh \ annotate.cc annotate.hh \ restrictions.cc restrictions.hh \ - hmac.cc hmac.hh \ + hmac.cc hmac.hh \ globish.cc globish.hh \ \ cleanup.hh unit_tests.hh interner.hh \ =============================================== --- sanity.cc 2a3933f0a61318d32c1f2061fcadd106761fce87 +++ sanity.cc 2396edeaed987d915d9ad8665d1c3e24534043b6 @@ -48,6 +48,7 @@ if (out) { copy(logbuf.begin(), logbuf.end(), ostream_iterator(out)); + copy(gasp_dump.begin(), gasp_dump.end(), ostream_iterator(out)); ui.inform(string("wrote debugging log to ") + filename + "\n"); } else @@ -209,6 +210,7 @@ format("%s:%d: invariant '%s' violated\n") % file % line % expr; log(fmt, file.c_str(), line); + gasp(); throw logic_error(fmt.str()); } @@ -223,5 +225,36 @@ format("%s:%d: index '%s' = %d overflowed vector '%s' with size %d\n") % file % line % idx_expr % idx % vec_expr % sz; log(fmt, file.c_str(), line); + gasp(); throw logic_error(fmt.str()); } + +// Last gasp dumps + +void +sanity::gasp() +{ + L(F("saving current work set: %i items") % musings.size()); + std::ostringstream out(gasp_dump); + out << F("Current work set: %i items\n") % musings.size(); + for (std::vector::const_iterator + i = musings.begin(); i != musings.end(); ++i) + (*i)->gasp(out); + L(F("finished saving work set")); + if (debug) + { + ui.inform("contents of work set:"); + ui.inform(gasp_dump); + } +} + +MusingI::MusingI() +{ + global_sanity.musings.push_back(this); +} + +MusingI::~MusingI() +{ + I(global_sanity.musings.back() == this); + global_sanity.musings.pop_back(); +} =============================================== --- sanity.hh 2fea4a99d4e7e8b108c8168d974243c6fcb3212a +++ sanity.hh c7fe8c720645f18d069058004cc1c3dd9db3f00a @@ -9,6 +9,7 @@ #include #include #include +#include #include "boost/format.hpp" #include "boost/circular_buffer.hpp" @@ -37,6 +38,8 @@ std::string what; }; +class MusingI; + struct sanity { sanity(); ~sanity(); @@ -52,6 +55,8 @@ bool relaxed; boost::circular_buffer logbuf; std::string filename; + std::string gasp_dump; + std::vector musings; void log(boost::format const & fmt, char const * file, int line); @@ -70,6 +75,7 @@ unsigned long sz, unsigned long idx, std::string const & file, int line) NORETURN; + void gasp(); }; typedef std::runtime_error oops; @@ -193,4 +199,41 @@ +// Last gasp dumps + +class MusingI +{ +public: + MusingI(); + virtual ~MusingI(); + virtual void gasp(std::ostream & out) const = 0; +}; + +template +class Musing : public MusingI +{ +public: + Musing(T const & obj, char const * name, char const * file, int line, char const * func) + : obj(obj), name(name), file(file), line(line), func(func) {} + virtual void gasp(std::ostream & out) const; +private: + T const & obj; + char const * name; + char const * file; + int line; + char const * func; +}; + +template void +Musing::gasp(std::ostream & out) const +{ + out << F("----------------- begin '%s' (in %s, at %s:%d) -----------------\n") % name % func % file % line; + dump(obj, out); + out << F("------------------- end '%s' (in %s, at %s:%d) -----------------\n") % name % func % file % line; +} + +#define M(obj) Musing(obj, #obj, __FILE__, __LINE__, __PRETTY_FUNCTION__); + + + #endif // __SANITY_HH__