Add DEBUG() macro for debugging that can be turned on and off with a
[pintos-anon] / src / lib / debug.c
1 #include "debug.h"
2 #include <stdarg.h>
3 #include "interrupt.h"
4 #include "lib.h"
5
6 #define MAX_CLASSES 16
7 static bool all_enabled;
8 static const char *enabled_classes[MAX_CLASSES];
9 static size_t enabled_cnt;
10
11 /* Enables the debug message classes specified in CLASSES.  The
12    string CLASSES is modified by and becomes owned by this
13    function. */
14 void
15 debug_enable (char *classes) 
16 {
17   char *class, *save;
18
19   for (class = strtok_r (classes, ",", &save); class != NULL;
20        class = strtok_r (NULL, ",", &save))
21     {
22       if (strcmp (class, "all") && enabled_cnt < MAX_CLASSES)
23         enabled_classes[enabled_cnt++] = class;
24       else
25         all_enabled = true;
26     }
27 }
28
29 /* Checks whether CLASS is enabled. */
30 static bool
31 class_is_enabled (const char *class) 
32 {
33   size_t i;
34   
35   if (all_enabled)
36     return true;
37
38   for (i = 0; i < enabled_cnt; i++)
39     if (!strcmp (enabled_classes[i], class))
40       return true;
41
42   return false;
43 }
44
45 /* Prints a debug message along with the source file name, line
46    number, and function name of where it was emitted.  CLASS is
47    used to filter out unwanted messages. */
48 void
49 debug_message (const char *file, int line, const char *function,
50                const char *class, const char *message, ...) 
51 {
52   if (class_is_enabled (class)) 
53     {
54       va_list args;
55
56       enum if_level old_level = intr_disable ();
57       printk ("%s:%d: %s(): ", file, line, function);
58       va_start (args, message);
59       vprintk (message, args);
60       printk ("\n");
61       va_end (args);
62       intr_set_level (old_level);
63     }
64 }
65
66 /* Halts the OS, printing the source file name, line number, and
67    function name, plus a user-specific message. */
68 void
69 debug_panic (const char *file, int line, const char *function,
70              const char *message, ...)
71 {
72   va_list args;
73
74   intr_disable ();
75
76   printk ("PANIC at %s:%d in %s(): ", file, line, function);
77   va_start (args, message);
78   vprintk (message, args);
79   printk ("\n");
80   va_end (args);
81
82   debug_backtrace ();
83
84   for (;;);
85 }
86
87 /* Prints the call stack, that is, a list of addresses in each of
88    the functions we are nested within.  gdb or addr2line may be
89    applied to kernel.o to translate these into file names, line
90    numbers, and function names.  */
91 void
92 debug_backtrace (void) 
93 {
94   void **frame;
95   
96   printk ("Call stack:");
97   for (frame = __builtin_frame_address (0);
98        frame != NULL && frame[0] != NULL;
99        frame = frame[0]) 
100     printk (" %p", frame[1]);
101   printk (".\n");
102 }