8fea5ab8bd
The set of processes to which a SIGKMESS signal is sent whenever new diagnostics messages are added to the kernel's message buffer, is now no longer hardcoded. Instead, processes can (un)register themselves to receive such notifications, by means of sys_diagctl(). Change-Id: I9d6ac006a5d9bbfad2757587a068fc1ec3cc083e
90 lines
2.5 KiB
C
90 lines
2.5 KiB
C
/* This file contains a collection of miscellaneous procedures:
|
|
* panic: abort MINIX due to a fatal error
|
|
* kputc: buffered putc used by kernel printf
|
|
*/
|
|
|
|
#include "kernel/kernel.h"
|
|
#include "arch_proto.h"
|
|
|
|
#include <minix/syslib.h>
|
|
#include <unistd.h>
|
|
#include <stdarg.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
|
|
#include <minix/sys_config.h>
|
|
|
|
#define ARE_PANICING 0xDEADC0FF
|
|
|
|
/*===========================================================================*
|
|
* panic *
|
|
*===========================================================================*/
|
|
void panic(const char *fmt, ...)
|
|
{
|
|
va_list arg;
|
|
/* The system has run aground of a fatal kernel error. Terminate execution. */
|
|
if (kinfo.minix_panicing == ARE_PANICING) {
|
|
reset();
|
|
}
|
|
kinfo.minix_panicing = ARE_PANICING;
|
|
if (fmt != NULL) {
|
|
printf("kernel panic: ");
|
|
va_start(arg, fmt);
|
|
vprintf(fmt, arg);
|
|
printf("\n");
|
|
}
|
|
|
|
printf("kernel on CPU %d: ", cpuid);
|
|
util_stacktrace();
|
|
|
|
#if 0
|
|
if(get_cpulocal_var(proc_ptr)) {
|
|
printf("current process : ");
|
|
proc_stacktrace(get_cpulocal_var(proc_ptr));
|
|
}
|
|
#endif
|
|
|
|
/* Abort MINIX. */
|
|
minix_shutdown(NULL);
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* kputc *
|
|
*===========================================================================*/
|
|
void kputc(c)
|
|
int c; /* character to append */
|
|
{
|
|
/* Accumulate a single character for a kernel message. Send a notification
|
|
* to the output drivers if an END_OF_KMESS is encountered.
|
|
*/
|
|
if (c != END_OF_KMESS) {
|
|
int maxblpos = sizeof(kmess.kmess_buf) - 2;
|
|
#ifdef DEBUG_SERIAL
|
|
if (kinfo.do_serial_debug) {
|
|
if(c == '\n')
|
|
ser_putc('\r');
|
|
ser_putc(c);
|
|
}
|
|
#endif
|
|
kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
|
|
kmess.kmess_buf[kmess.blpos] = c;
|
|
if (kmess.km_size < sizeof(kmess.km_buf))
|
|
kmess.km_size += 1;
|
|
kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
|
|
if(kmess.blpos == maxblpos) {
|
|
memmove(kmess.kmess_buf,
|
|
kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
|
|
} else kmess.blpos++;
|
|
} else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
|
|
send_diag_sig();
|
|
}
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* _exit *
|
|
*===========================================================================*/
|
|
void _exit(e)
|
|
int e; /* error code */
|
|
{
|
|
panic("_exit called from within the kernel, should not happen. (err %i)", e);
|
|
}
|