From eddac53ff60c579eff28134bde84783fe36d6214 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 15 Apr 2011 10:44:32 -0700 Subject: trace: reimplement the DTRACE function so it doesn't use a vector At the same time, rename the trace flags to debug flags since they have broader usage than simply tracing. This means that --trace-flags is now --debug-flags and --trace-help is now --debug-help --- src/base/debug.cc | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'src/base/debug.cc') 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 #include +#include #include +#include +#include #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 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 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(i->second); + if (f && f->status()) + cprintf("%s\n", f->name()); + } +} -- cgit v1.2.3