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
112
|
/*
** @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" );
}
|