8 #include "threads/init.h"
9 #include "threads/interrupt.h"
10 #include "threads/thread.h"
11 #include "threads/switch.h"
12 #include "threads/vaddr.h"
13 #include "devices/serial.h"
14 #include "devices/shutdown.h"
16 /* Halts the OS, printing the source file name, line number, and
17 function name, plus a user-specific message. */
19 debug_panic (const char *file, int line, const char *function,
20 const char *message, ...)
31 printf ("Kernel PANIC at %s:%d in %s(): ", file, line, function);
33 va_start (args, message);
34 vprintf (message, args);
41 printf ("Kernel PANIC recursion at %s:%d in %s().\n",
42 file, line, function);
45 /* Don't print anything: that's probably why we recursed. */
49 if (power_off_when_done)
50 shutdown_power_off ();
54 /* Print call stack of a thread.
55 The thread may be running, ready, or blocked. */
57 print_stacktrace(struct thread *t, void *aux UNUSED)
59 void *retaddr = NULL, **frame = NULL;
60 const char *status = "UNKNOWN";
79 printf ("Call stack of thread `%s' (status %s):", t->name, status);
81 if (t == thread_current())
83 frame = __builtin_frame_address (1);
84 retaddr = __builtin_return_address (0);
88 /* Retrieve the values of the base and instruction pointers
89 as they were saved when this thread called switch_threads. */
90 struct switch_threads_frame * saved_frame;
92 saved_frame = (struct switch_threads_frame *)t->stack;
94 /* Skip threads if they have been added to the all threads
95 list, but have never been scheduled.
96 We can identify because their `stack' member either points
97 at the top of their kernel stack page, or the
98 switch_threads_frame's 'eip' member points at switch_entry.
99 See also threads.c. */
100 if (t->stack == (uint8_t *)t + PGSIZE || saved_frame->eip == switch_entry)
102 printf (" thread was never scheduled.\n");
106 frame = (void **) saved_frame->ebp;
107 retaddr = (void *) saved_frame->eip;
110 printf (" %p", retaddr);
111 for (; (uintptr_t) frame >= 0x1000 && frame[0] != NULL; frame = frame[0])
112 printf (" %p", frame[1]);
116 /* Prints call stack of all threads. */
118 debug_backtrace_all (void)
120 enum intr_level oldlevel = intr_disable ();
122 thread_foreach (print_stacktrace, 0);
123 intr_set_level (oldlevel);