1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/*
** @file klibc.c
**
** @author Warren R. Carithers
**
** Additional support functions for the kernel.
**
*/
#define KERNEL_SRC
#include <klib.h>
#include <cio.h>
#include <procs.h>
#include <support.h>
/**
** Name: put_char_or_code( ch )
**
** Description: Prints a character on the console, unless it
** is a non-printing character, in which case its hex code
** is printed
**
** @param ch The character to be printed
*/
void put_char_or_code(int ch)
{
if (ch >= ' ' && ch < 0x7f) {
cio_putchar(ch);
} else {
cio_printf("\\x%02x", ch);
}
}
/**
** Name: backtrace
**
** Perform a stack backtrace
**
** @param ebp Initial EBP to use
** @param args Number of function argument values to print
*/
void backtrace(uint32_t *ebp, uint_t args)
{
cio_puts("Trace: ");
if (ebp == NULL) {
cio_puts("NULL ebp, no trace possible\n");
return;
} else {
cio_putchar('\n');
}
while (ebp != NULL) {
// get return address and report it and EBP
uint32_t ret = ebp[1];
cio_printf(" ebp %08x ret %08x args", (uint32_t)ebp, ret);
// print the requested number of function arguments
for (uint_t i = 0; i < args; ++i) {
cio_printf(" [%u] %08x", i + 1, ebp[2 + i]);
}
cio_putchar('\n');
// follow the chain
ebp = (uint32_t *)*ebp;
}
}
/**
** kpanic - kernel-level panic routine
**
** usage: kpanic( msg )
**
** Prefix routine for panic() - can be expanded to do other things
** (e.g., printing a stack traceback)
**
** @param msg[in] String containing a relevant message to be printed,
** or NULL
*/
void kpanic(const char *msg)
{
cio_puts("\n\n***** KERNEL PANIC *****\n\n");
if (msg) {
cio_printf("%s\n", msg);
}
delay(DELAY_5_SEC); // approximately
// dump a bunch of potentially useful information
// dump the contents of the current PCB
pcb_dump("Current", current, true);
// dump the basic info about what's in the process table
ptable_dump_counts();
// dump information about the queues
pcb_queue_dump("R", ready, true);
pcb_queue_dump("W", waiting, true);
pcb_queue_dump("S", sleeping, true);
pcb_queue_dump("Z", zombie, true);
pcb_queue_dump("I", sioread, true);
// perform a stack backtrace
backtrace((uint32_t *)r_ebp(), 3);
// could dump other stuff here, too
panic("KERNEL PANIC");
}
|