Add DEBUG() macro for debugging that can be turned on and off with a
[pintos-anon] / src / lib / debug.c
index fafbc8c1acc69de41a5dfb4104f910c2365f4c84..3d9a9b1e28f159f1d1dc0a82d7e117c6a6f02bac 100644 (file)
@@ -3,25 +3,93 @@
 #include "interrupt.h"
 #include "lib.h"
 
+#define MAX_CLASSES 16
+static bool all_enabled;
+static const char *enabled_classes[MAX_CLASSES];
+static size_t enabled_cnt;
+
+/* Enables the debug message classes specified in CLASSES.  The
+   string CLASSES is modified by and becomes owned by this
+   function. */
+void
+debug_enable (char *classes) 
+{
+  char *class, *save;
+
+  for (class = strtok_r (classes, ",", &save); class != NULL;
+       class = strtok_r (NULL, ",", &save))
+    {
+      if (strcmp (class, "all") && enabled_cnt < MAX_CLASSES)
+        enabled_classes[enabled_cnt++] = class;
+      else
+        all_enabled = true;
+    }
+}
+
+/* Checks whether CLASS is enabled. */
+static bool
+class_is_enabled (const char *class) 
+{
+  size_t i;
+  
+  if (all_enabled)
+    return true;
+
+  for (i = 0; i < enabled_cnt; i++)
+    if (!strcmp (enabled_classes[i], class))
+      return true;
+
+  return false;
+}
+
+/* Prints a debug message along with the source file name, line
+   number, and function name of where it was emitted.  CLASS is
+   used to filter out unwanted messages. */
+void
+debug_message (const char *file, int line, const char *function,
+               const char *class, const char *message, ...) 
+{
+  if (class_is_enabled (class)) 
+    {
+      va_list args;
+
+      enum if_level old_level = intr_disable ();
+      printk ("%s:%d: %s(): ", file, line, function);
+      va_start (args, message);
+      vprintk (message, args);
+      printk ("\n");
+      va_end (args);
+      intr_set_level (old_level);
+    }
+}
+
+/* Halts the OS, printing the source file name, line number, and
+   function name, plus a user-specific message. */
 void
-panic (const char *format, ...)
+debug_panic (const char *file, int line, const char *function,
+             const char *message, ...)
 {
   va_list args;
 
   intr_disable ();
 
-  va_start (args, format);
-  vprintk (format, args);
+  printk ("PANIC at %s:%d in %s(): ", file, line, function);
+  va_start (args, message);
+  vprintk (message, args);
   printk ("\n");
   va_end (args);
 
-  backtrace ();
+  debug_backtrace ();
 
   for (;;);
 }
 
+/* Prints the call stack, that is, a list of addresses in each of
+   the functions we are nested within.  gdb or addr2line may be
+   applied to kernel.o to translate these into file names, line
+   numbers, and function names.  */
 void
-backtrace (void) 
+debug_backtrace (void) 
 {
   void **frame;