Add a suggestion to use `backtrace' and a reference to the manual to
[pintos-anon] / src / lib / debug.c
index 534fc02c6d9066438f04e3538bd4a09dd6c3a741..4f0f5f303cf933dab61c1b1e6f723d7ed7b8bb6b 100644 (file)
@@ -1,7 +1,16 @@
-#include "debug.h"
+#include <debug.h>
 #include <stdarg.h>
-#include "interrupt.h"
-#include "lib.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef KERNEL
+#include "threads/init.h"
+#include "threads/interrupt.h"
+#include "devices/serial.h"
+#else
+#include <syscall.h>
+#endif
 
 #define MAX_CLASSES 16
 static bool all_enabled;
@@ -39,52 +48,75 @@ debug_message (const char *file, int line, const char *function,
     {
       va_list args;
 
+#ifdef KERNEL
       enum intr_level old_level = intr_disable ();
-      printk ("%s:%d: %s(): ", file, line, function);
+#endif
+      printf ("%s:%d: %s(): ", file, line, function);
       va_start (args, message);
-      vprintk (message, args);
-      printk ("\n");
+      vprintf (message, args);
+      printf ("\n");
       va_end (args);
+#ifdef KERNEL
       intr_set_level (old_level);
+#endif
     }
 }
 
-/* Halts the OS, printing the source file name, line number, and
-   function name, plus a user-specific message. */
+/* Halts the OS or user program, printing the source file name,
+   line number, and function name, plus a user-specific
+   message. */
 void
 debug_panic (const char *file, int line, const char *function,
              const char *message, ...)
 {
   va_list args;
 
+#ifdef KERNEL
   intr_disable ();
+#endif
+
+#ifdef KERNEL
+  printf ("Kernel PANIC at %s:%d in %s(): ", file, line, function);
+#else
+  printf ("User process panic at %s:%d in %s(): ", file, line, function);
+#endif
 
-  printk ("PANIC at %s:%d in %s(): ", file, line, function);
   va_start (args, message);
-  vprintk (message, args);
-  printk ("\n");
+  vprintf (message, args);
+  printf ("\n");
   va_end (args);
 
   debug_backtrace ();
 
+  printf ("The `backtrace' program can make call stacks useful.\n"
+          "Read \"Backtraces\" in the \"Debugging Tools\" chapter\n"
+          "of the Pintos documentation for more information.\n");
+  
+#ifdef KERNEL
+  serial_flush ();
+  if (power_off_when_done)
+    power_off ();
   for (;;);
+#else
+  exit (1);
+#endif
 }
 
-/* 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.  */
+/* Prints the call stack, that is, a list of addresses, one 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
 debug_backtrace (void) 
 {
   void **frame;
   
-  printk ("Call stack:");
+  printf ("Call stack:");
   for (frame = __builtin_frame_address (0);
        frame != NULL && frame[0] != NULL;
        frame = frame[0]) 
-    printk (" %p", frame[1]);
-  printk (".\n");
+    printf (" %p", frame[1]);
+  printf (".\n");
 }
 \f