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