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