summaryrefslogtreecommitdiff
path: root/src/base/debug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/debug.cc')
-rw-r--r--src/base/debug.cc135
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());
+ }
+}