diff options
Diffstat (limited to 'src/base/debug.cc')
-rw-r--r-- | src/base/debug.cc | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/base/debug.cc b/src/base/debug.cc index 6f01b3fc0..be301da07 100644 --- a/src/base/debug.cc +++ b/src/base/debug.cc @@ -31,12 +31,24 @@ #include <sys/types.h> #include <unistd.h> +#include <algorithm> #include <csignal> +#include <map> +#include <vector> #include "base/cprintf.hh" +#include "base/debug.hh" +#include "base/misc.hh" + +using namespace std; namespace Debug { +// +// This function will cause the process to signal itself with a +// SIGTRAP which is ignored if not in gdb, but will cause the debugger +// to break if in gdb. +// void breakpoint() { @@ -47,4 +59,127 @@ breakpoint() #endif } +// +// Flags for debugging purposes. Primarily for trace.hh +// +typedef std::map<string, Flag *> FlagsMap; +int allFlagsVersion = 0; +FlagsMap & +allFlags() +{ + static FlagsMap flags; + return flags; +} + +Flag * +findFlag(const std::string &name) +{ + FlagsMap::iterator i = allFlags().find(name); + if (i == allFlags().end()) + return NULL; + return i->second; +} + +Flag::Flag(const char *name, const char *desc) + : _name(name), _desc(desc) +{ + pair<FlagsMap::iterator, bool> result = + allFlags().insert(make_pair(name, this)); + + if (!result.second) + panic("Flag %s already defined!", name); + + ++allFlagsVersion; +} + +Flag::~Flag() +{ + // should find and remove flag. +} + +void +CompoundFlag::enable() +{ + SimpleFlag::enable(); + for_each(flags.begin(), flags.end(), mem_fun(&Flag::enable)); +} + +void +CompoundFlag::disable() +{ + SimpleFlag::disable(); + for_each(flags.begin(), flags.end(), mem_fun(&Flag::disable)); +} + +struct AllFlags : public Flag +{ + AllFlags() + : Flag("All", "All Flags") + {} + + void + enable() + { + FlagsMap::iterator i = allFlags().begin(); + FlagsMap::iterator end = allFlags().end(); + for (; i != end; ++i) + if (i->second != this) + i->second->enable(); + } + + void + disable() + { + FlagsMap::iterator i = allFlags().begin(); + FlagsMap::iterator end = allFlags().end(); + for (; i != end; ++i) + if (i->second != this) + i->second->enable(); + } +}; + +AllFlags theAllFlags; +Flag *const All = &theAllFlags; + +bool +changeFlag(const char *s, bool value) +{ + Flag *f = findFlag(s); + if (!f) + return false; + + if (value) + f->enable(); + else + f->disable(); + + return true; +} + } // namespace Debug + +// add a set of functions that can easily be invoked from gdb +void +setDebugFlag(const char *string) +{ + Debug::changeFlag(string, true); +} + +void +clearDebugFlag(const char *string) +{ + Debug::changeFlag(string, false); +} + +void +dumpDebugFlags() +{ + using namespace Debug; + FlagsMap::iterator i = allFlags().begin(); + FlagsMap::iterator end = allFlags().end(); + for (; i != end; ++i) { + SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second); + if (f && f->status()) + cprintf("%s\n", f->name()); + } +} |