summaryrefslogtreecommitdiff
path: root/kern/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'kern/debug.c')
-rw-r--r--kern/debug.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/kern/debug.c b/kern/debug.c
new file mode 100644
index 0000000..eda5b2a
--- /dev/null
+++ b/kern/debug.c
@@ -0,0 +1,192 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <mach_kdb.h>
+#include <norma_ipc.h>
+#include <cpus.h>
+
+#include "cpu_number.h"
+#include <kern/lock.h>
+#include <sys/varargs.h>
+#include <kern/thread.h>
+
+
+
+extern void cnputc();
+void Debugger();
+
+#if MACH_KDB
+extern int db_breakpoints_inserted;
+#endif
+
+#if NCPUS>1
+simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
+#endif
+
+void
+Assert(char *exp, char *file, int line)
+{
+#if NCPUS > 1
+ simple_lock(&Assert_print_lock);
+ printf("{%d} Assertion failed: file \"%s\", line %d\n",
+ cpu_number(), file, line);
+ simple_unlock(&Assert_print_lock);
+#else
+ printf("Assertion `%s' failed in file \"%s\", line %d\n",
+ exp, file, line);
+#endif
+
+#if MACH_KDB
+ if (db_breakpoints_inserted)
+#endif
+ Debugger("assertion failure");
+}
+
+void Debugger(message)
+ char * message;
+{
+#if !MACH_KDB
+ panic("Debugger invoked, but there isn't one!");
+#endif
+
+#ifdef lint
+ message++;
+#endif /* lint */
+
+#if defined(vax) || defined(PC532)
+ asm("bpt");
+#endif /* vax */
+
+#ifdef sun3
+ current_thread()->pcb->flag |= TRACE_KDB;
+ asm("orw #0x00008000,sr");
+#endif /* sun3 */
+#ifdef sun4
+ current_thread()->pcb->pcb_flag |= TRACE_KDB;
+ asm("ta 0x81");
+#endif /* sun4 */
+
+#if defined(mips ) || defined(luna88k) || defined(i860) || defined(alpha)
+ gimmeabreak();
+#endif
+
+#ifdef i386
+ asm("int3");
+#endif
+}
+
+/* Be prepared to panic anytime,
+ even before panic_init() gets called from the "normal" place in kern/startup.c.
+ (panic_init() still needs to be called from there
+ to make sure we get initialized before starting multiple processors.) */
+boolean_t panic_lock_initialized = FALSE;
+decl_simple_lock_data(, panic_lock)
+
+char *panicstr;
+int paniccpu;
+
+void
+panic_init()
+{
+ if (!panic_lock_initialized)
+ {
+ panic_lock_initialized = TRUE;
+ simple_lock_init(&panic_lock);
+ }
+}
+
+/*VARARGS1*/
+void
+panic(s, va_alist)
+ char * s;
+ va_dcl
+{
+ va_list listp;
+#if NORMA_IPC
+ extern int _node_self; /* node_self() may not be callable yet */
+#endif /* NORMA_IPC */
+
+ panic_init();
+
+ simple_lock(&panic_lock);
+ if (panicstr) {
+ if (cpu_number() != paniccpu) {
+ simple_unlock(&panic_lock);
+ halt_cpu();
+ /* NOTREACHED */
+ }
+ }
+ else {
+ panicstr = s;
+ paniccpu = cpu_number();
+ }
+ simple_unlock(&panic_lock);
+ printf("panic");
+#if NORMA_IPC
+ printf("(node %U)", _node_self);
+#endif
+#if NCPUS > 1
+ printf("(cpu %U)", paniccpu);
+#endif
+ printf(": ");
+ va_start(listp);
+ _doprnt(s, &listp, cnputc, 0);
+ va_end(listp);
+ printf("\n");
+
+ /* Give the user time to see the message */
+ {
+ int i = 60; /* seconds */
+ while (i--)
+ delay (1000000); /* microseconds */
+ }
+
+#if MACH_KDB
+ Debugger("panic");
+#else
+ halt_all_cpus (1);
+#endif
+}
+
+/*
+ * We'd like to use BSD's log routines here...
+ */
+/*VARARGS2*/
+void
+log(level, fmt, va_alist)
+ int level;
+ char * fmt;
+ va_dcl
+{
+ va_list listp;
+
+#ifdef lint
+ level++;
+#endif
+ va_start(listp);
+ _doprnt(fmt, &listp, cnputc, 0);
+ va_end(listp);
+}