panic() cleanup.
[minix.git] / kernel / debug.c
blob407a8ebfd4495ed89d0689d6e9e319ef1428af0a
1 /* This file implements kernel debugging functionality that is not included
2 * in the standard kernel. Available functionality includes timing of lock
3 * functions and sanity checking of the scheduling queues.
4 */
6 #include "kernel.h"
7 #include "proc.h"
8 #include "debug.h"
10 #include <minix/sysutil.h>
11 #include <limits.h>
12 #include <string.h>
14 #if DEBUG_SCHED_CHECK /* only include code if enabled */
16 #define MAX_LOOP (NR_PROCS + NR_TASKS)
18 PUBLIC void
19 check_runqueues_f(char *file, int line)
21 int q, l = 0;
22 register struct proc *xp;
24 FIXME("check_runqueues being done");
26 #define MYPANIC(msg) { \
27 panic("check_runqueues:%s:%d: %s\n", file, line, msg); \
30 for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
31 xp->p_found = 0;
32 if (l++ > MAX_LOOP) { MYPANIC("check error"); }
35 for (q=l=0; q < NR_SCHED_QUEUES; q++) {
36 if (rdy_head[q] && !rdy_tail[q]) {
37 printf("head but no tail in %d\n", q);
38 MYPANIC("scheduling error");
40 if (!rdy_head[q] && rdy_tail[q]) {
41 printf("tail but no head in %d\n", q);
42 MYPANIC("scheduling error");
44 if (rdy_tail[q] && rdy_tail[q]->p_nextready != NIL_PROC) {
45 printf("tail and tail->next not null in %d\n", q);
46 MYPANIC("scheduling error");
48 for(xp = rdy_head[q]; xp != NIL_PROC; xp = xp->p_nextready) {
49 vir_bytes vxp = (vir_bytes) xp, dxp;
50 if(vxp < (vir_bytes) BEG_PROC_ADDR || vxp >= (vir_bytes) END_PROC_ADDR) {
51 MYPANIC("xp out of range");
53 dxp = vxp - (vir_bytes) BEG_PROC_ADDR;
54 if(dxp % sizeof(struct proc)) {
55 MYPANIC("xp not a real pointer");
57 if(xp->p_magic != PMAGIC) {
58 MYPANIC("magic wrong in xp");
60 if (RTS_ISSET(xp, RTS_SLOT_FREE)) {
61 printf("scheduling error: dead proc q %d %d\n",
62 q, xp->p_endpoint);
63 MYPANIC("dead proc on run queue");
65 if (!xp->p_ready) {
66 printf("scheduling error: unready on runq %d proc %d\n",
67 q, xp->p_nr);
68 MYPANIC("found unready process on run queue");
70 if (xp->p_priority != q) {
71 printf("scheduling error: wrong priority q %d proc %d ep %d name %s\n",
72 q, xp->p_nr, xp->p_endpoint, xp->p_name);
73 MYPANIC("wrong priority");
75 if (xp->p_found) {
76 printf("scheduling error: double sched q %d proc %d\n",
77 q, xp->p_nr);
78 MYPANIC("proc more than once on scheduling queue");
80 xp->p_found = 1;
81 if (xp->p_nextready == NIL_PROC && rdy_tail[q] != xp) {
82 printf("sched err: last element not tail q %d proc %d\n",
83 q, xp->p_nr);
84 MYPANIC("scheduling error");
86 if (l++ > MAX_LOOP) MYPANIC("loop in schedule queue?");
90 l = 0;
91 for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
92 if(xp->p_magic != PMAGIC)
93 MYPANIC("p_magic wrong in proc table");
94 if (isemptyp(xp))
95 continue;
96 if(xp->p_ready && ! xp->p_found) {
97 printf("sched error: ready proc %d not on queue\n", xp->p_nr);
98 MYPANIC("ready proc not on scheduling queue");
99 if (l++ > MAX_LOOP) { MYPANIC("loop in debug.c?"); }
104 #endif /* DEBUG_SCHED_CHECK */
106 PUBLIC char *
107 rtsflagstr(int flags)
109 static char str[100];
110 str[0] = '\0';
112 #define FLAG(n) if(flags & n) { strcat(str, #n " "); }
114 FLAG(RTS_SLOT_FREE);
115 FLAG(RTS_PROC_STOP);
116 FLAG(RTS_SENDING);
117 FLAG(RTS_RECEIVING);
118 FLAG(RTS_SIGNALED);
119 FLAG(RTS_SIG_PENDING);
120 FLAG(RTS_P_STOP);
121 FLAG(RTS_NO_PRIV);
122 FLAG(RTS_NO_ENDPOINT);
123 FLAG(RTS_VMINHIBIT);
124 FLAG(RTS_PAGEFAULT);
125 FLAG(RTS_VMREQUEST);
126 FLAG(RTS_VMREQTARGET);
127 FLAG(RTS_PREEMPTED);
128 FLAG(RTS_NO_QUANTUM);
130 return str;
133 PUBLIC char *
134 miscflagstr(int flags)
136 static char str[100];
137 str[0] = '\0';
139 FLAG(MF_REPLY_PEND);
140 FLAG(MF_ASYNMSG);
141 FLAG(MF_FULLVM);
142 FLAG(MF_DELIVERMSG);
143 FLAG(MF_KCALL_RESUME);
145 return str;