|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26:
1.1.1.4 root 27: #include <mach/xen.h>
1.1.1.3 root 28:
1.1.1.4 root 29: #include <kern/printf.h>
30: #include <stdarg.h>
1.1 root 31:
32: #include "cpu_number.h"
33: #include <kern/lock.h>
34: #include <kern/thread.h>
35:
1.1.1.4 root 36: #include <kern/debug.h>
1.1 root 37:
1.1.1.4 root 38: #include <machine/loose_ends.h>
39: #include <machine/model_dep.h>
1.1 root 40:
1.1.1.5 ! root 41: #include <device/cons.h>
1.1 root 42:
43: #if NCPUS>1
44: simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
45: #endif
46:
1.1.1.4 root 47: static void
48: do_cnputc(char c, vm_offset_t offset)
49: {
50: cnputc(c);
51: }
52:
1.1 root 53: void
1.1.1.5 ! root 54: Assert(const char *exp, const char *file, int line)
1.1 root 55: {
56: #if NCPUS > 1
57: simple_lock(&Assert_print_lock);
58: printf("{%d} Assertion failed: file \"%s\", line %d\n",
59: cpu_number(), file, line);
60: simple_unlock(&Assert_print_lock);
61: #else
62: printf("Assertion `%s' failed in file \"%s\", line %d\n",
63: exp, file, line);
64: #endif
65:
66: Debugger("assertion failure");
67: }
68:
1.1.1.4 root 69: void SoftDebugger(message)
1.1.1.5 ! root 70: const char *message;
1.1 root 71: {
1.1.1.4 root 72: printf("Debugger invoked: %s\n", message);
73:
1.1 root 74: #if !MACH_KDB
1.1.1.4 root 75: printf("But no debugger, continuing.\n");
76: return;
1.1 root 77: #endif
78:
79: #if defined(vax) || defined(PC532)
80: asm("bpt");
81: #endif /* vax */
82:
83: #ifdef sun3
84: current_thread()->pcb->flag |= TRACE_KDB;
85: asm("orw #0x00008000,sr");
86: #endif /* sun3 */
87: #ifdef sun4
88: current_thread()->pcb->pcb_flag |= TRACE_KDB;
89: asm("ta 0x81");
90: #endif /* sun4 */
91:
1.1.1.4 root 92: #if defined(mips ) || defined(i860) || defined(alpha)
1.1 root 93: gimmeabreak();
94: #endif
95:
1.1.1.4 root 96: #if defined(__i386__)
1.1 root 97: asm("int3");
98: #endif
99: }
100:
1.1.1.4 root 101: void Debugger(message)
1.1.1.5 ! root 102: const char *message;
1.1.1.4 root 103: {
104: #if !MACH_KDB
105: panic("Debugger invoked, but there isn't one!");
106: #endif
107:
108: SoftDebugger(message);
109:
110: panic("Debugger returned!");
111: }
112:
1.1 root 113: /* Be prepared to panic anytime,
114: even before panic_init() gets called from the "normal" place in kern/startup.c.
115: (panic_init() still needs to be called from there
116: to make sure we get initialized before starting multiple processors.) */
117: boolean_t panic_lock_initialized = FALSE;
118: decl_simple_lock_data(, panic_lock)
119:
1.1.1.3 root 120: const char *panicstr;
1.1 root 121: int paniccpu;
122:
123: void
1.1.1.4 root 124: panic_init(void)
1.1 root 125: {
126: if (!panic_lock_initialized)
127: {
128: panic_lock_initialized = TRUE;
129: simple_lock_init(&panic_lock);
130: }
131: }
132:
1.1.1.4 root 133: #if ! MACH_KBD
134: extern boolean_t reboot_on_panic;
135: #endif
136:
1.1 root 137: /*VARARGS1*/
138: void
1.1.1.3 root 139: panic(const char *s, ...)
1.1 root 140: {
141: va_list listp;
142:
143: panic_init();
144:
145: simple_lock(&panic_lock);
146: if (panicstr) {
147: if (cpu_number() != paniccpu) {
148: simple_unlock(&panic_lock);
149: halt_cpu();
150: /* NOTREACHED */
151: }
152: }
153: else {
154: panicstr = s;
155: paniccpu = cpu_number();
156: }
157: simple_unlock(&panic_lock);
158: printf("panic");
159: #if NCPUS > 1
160: printf("(cpu %U)", paniccpu);
161: #endif
162: printf(": ");
1.1.1.3 root 163: va_start(listp, s);
1.1.1.4 root 164: _doprnt(s, listp, do_cnputc, 0, 0);
1.1 root 165: va_end(listp);
166: printf("\n");
167:
1.1.1.4 root 168: #if MACH_KDB
169: Debugger("panic");
170: #else
171: # ifdef MACH_HYP
172: hyp_crash();
173: # else
1.1 root 174: /* Give the user time to see the message */
175: {
1.1.1.2 root 176: int i = 1000; /* seconds */
1.1 root 177: while (i--)
178: delay (1000000); /* microseconds */
179: }
180:
1.1.1.4 root 181: halt_all_cpus (reboot_on_panic);
182: # endif /* MACH_HYP */
1.1 root 183: #endif
184: }
185:
186: /*
187: * We'd like to use BSD's log routines here...
188: */
189: /*VARARGS2*/
190: void
1.1.1.3 root 191: log(int level, const char *fmt, ...)
1.1 root 192: {
193: va_list listp;
194:
1.1.1.3 root 195: va_start(listp, fmt);
1.1.1.4 root 196: _doprnt(fmt, listp, do_cnputc, 0, 0);
1.1 root 197: va_end(listp);
198: }
1.1.1.4 root 199:
1.1.1.5 ! root 200: /* GCC references this for stack protection. */
1.1.1.4 root 201: unsigned char __stack_chk_guard [ sizeof (vm_offset_t) ] =
202: {
203: [ sizeof (vm_offset_t) - 3 ] = '\r',
204: [ sizeof (vm_offset_t) - 2 ] = '\n',
205: [ sizeof (vm_offset_t) - 1 ] = 0xff,
206: };
207:
208: void
209: __stack_chk_fail (void)
210: {
211: panic("stack smashing detected");
212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.