|
|
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.3 ! root 27: #include <stdarg.h>
! 28:
1.1 root 29: #include <mach_kdb.h>
30: #include <norma_ipc.h>
31: #include <cpus.h>
32:
33: #include "cpu_number.h"
34: #include <kern/lock.h>
35: #include <kern/thread.h>
36:
1.1.1.3 ! root 37: #warning missing include for panic()
! 38: void panic(const char *s, ...);
1.1 root 39:
40:
41: extern void cnputc();
42: void Debugger();
43:
44: #if MACH_KDB
45: extern int db_breakpoints_inserted;
46: #endif
47:
48: #if NCPUS>1
49: simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
50: #endif
51:
52: void
53: Assert(char *exp, char *file, int line)
54: {
55: #if NCPUS > 1
56: simple_lock(&Assert_print_lock);
57: printf("{%d} Assertion failed: file \"%s\", line %d\n",
58: cpu_number(), file, line);
59: simple_unlock(&Assert_print_lock);
60: #else
61: printf("Assertion `%s' failed in file \"%s\", line %d\n",
62: exp, file, line);
63: #endif
64:
65: #if MACH_KDB
66: if (db_breakpoints_inserted)
67: #endif
68: Debugger("assertion failure");
69: }
70:
71: void Debugger(message)
72: char * message;
73: {
74: #if !MACH_KDB
75: panic("Debugger invoked, but there isn't one!");
76: #endif
77:
78: #ifdef lint
79: message++;
80: #endif /* lint */
81:
82: #if defined(vax) || defined(PC532)
83: asm("bpt");
84: #endif /* vax */
85:
86: #ifdef sun3
87: current_thread()->pcb->flag |= TRACE_KDB;
88: asm("orw #0x00008000,sr");
89: #endif /* sun3 */
90: #ifdef sun4
91: current_thread()->pcb->pcb_flag |= TRACE_KDB;
92: asm("ta 0x81");
93: #endif /* sun4 */
94:
95: #if defined(mips ) || defined(luna88k) || defined(i860) || defined(alpha)
96: gimmeabreak();
97: #endif
98:
99: #ifdef i386
100: asm("int3");
101: #endif
102: }
103:
104: /* Be prepared to panic anytime,
105: even before panic_init() gets called from the "normal" place in kern/startup.c.
106: (panic_init() still needs to be called from there
107: to make sure we get initialized before starting multiple processors.) */
108: boolean_t panic_lock_initialized = FALSE;
109: decl_simple_lock_data(, panic_lock)
110:
1.1.1.3 ! root 111: const char *panicstr;
1.1 root 112: int paniccpu;
113:
114: void
115: panic_init()
116: {
117: if (!panic_lock_initialized)
118: {
119: panic_lock_initialized = TRUE;
120: simple_lock_init(&panic_lock);
121: }
122: }
123:
124: /*VARARGS1*/
125: void
1.1.1.3 ! root 126: panic(const char *s, ...)
1.1 root 127: {
128: va_list listp;
129: #if NORMA_IPC
130: extern int _node_self; /* node_self() may not be callable yet */
131: #endif /* NORMA_IPC */
132:
133: panic_init();
134:
135: simple_lock(&panic_lock);
136: if (panicstr) {
137: if (cpu_number() != paniccpu) {
138: simple_unlock(&panic_lock);
139: halt_cpu();
140: /* NOTREACHED */
141: }
142: }
143: else {
144: panicstr = s;
145: paniccpu = cpu_number();
146: }
147: simple_unlock(&panic_lock);
148: printf("panic");
149: #if NORMA_IPC
150: printf("(node %U)", _node_self);
151: #endif
152: #if NCPUS > 1
153: printf("(cpu %U)", paniccpu);
154: #endif
155: printf(": ");
1.1.1.3 ! root 156: va_start(listp, s);
1.1 root 157: _doprnt(s, &listp, cnputc, 0);
158: va_end(listp);
159: printf("\n");
160:
161: /* Give the user time to see the message */
162: {
1.1.1.2 root 163: int i = 1000; /* seconds */
1.1 root 164: while (i--)
165: delay (1000000); /* microseconds */
166: }
167:
168: #if MACH_KDB
169: Debugger("panic");
170: #else
171: halt_all_cpus (1);
172: #endif
173: }
174:
175: /*
176: * We'd like to use BSD's log routines here...
177: */
178: /*VARARGS2*/
179: void
1.1.1.3 ! root 180: log(int level, const char *fmt, ...)
1.1 root 181: {
182: va_list listp;
183:
184: #ifdef lint
185: level++;
186: #endif
1.1.1.3 ! root 187: va_start(listp, fmt);
1.1 root 188: _doprnt(fmt, &listp, cnputc, 0);
189: va_end(listp);
190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.