#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;