void panic_context(unsigned int reason, void *ctx, const char *str, ...) { va_list listp; spl_t s; /* panic_caller is initialized to 0. If set, don't change it */ if ( ! panic_caller ) panic_caller = (unsigned long)(char *)__builtin_return_address(0); s = panic_prologue(str); kdb_printf("panic(cpu %d caller 0x%lx): ", (unsigned) paniccpu, panic_caller); if (str) { va_start(listp, str); _doprnt(str, &listp, consdebug_putc, 0); va_end(listp); } kdb_printf("\n"); /* * Release panicwait indicator so that other cpus may call Debugger(). */ panicwait = 0; DebuggerWithContext(reason, ctx, "panic"); panic_epilogue(s); }
void panic(const char *str, ...) { va_list listp; spl_t s; boolean_t old_doprnt_hide_pointers = doprnt_hide_pointers; /* panic_caller is initialized to 0. If set, don't change it */ if ( ! panic_caller ) panic_caller = (unsigned long)(char *)__builtin_return_address(0); s = panic_prologue(str); /* Never hide pointers from panic logs. */ doprnt_hide_pointers = FALSE; kdb_printf("panic(cpu %d caller 0x%lx): ", (unsigned) paniccpu, panic_caller); if (str) { va_start(listp, str); _doprnt(str, &listp, consdebug_putc, 0); va_end(listp); } kdb_printf("\n"); /* * Release panicwait indicator so that other cpus may call Debugger(). */ panicwait = 0; Debugger("panic"); doprnt_hide_pointers = old_doprnt_hide_pointers; panic_epilogue(s); }
void double_fault(const char* why) { SMP::global_lock(); fprintf(stderr, "\n\n%s\nDouble fault! \nCPU: %d, Reason: %s\n", panic_signature, SMP::cpu_id(), why); SMP::global_unlock(); panic_epilogue(why); }
/** * panic: * Display reason for kernel panic * Display last crash context value, if it exists * Display no-heap backtrace of stack * Call on_panic handler function, to allow application specific panic behavior * Print EOT character to stderr, to signal outside that PANIC output completed * If the handler returns, go to (permanent) sleep **/ void panic(const char* why) { cpu_enable_panicking(); if (PER_CPU(contexts).panics > 4) double_fault(why); const int current_cpu = SMP::cpu_id(); SMP::global_lock(); // Tell the System log that we have paniced SystemLog::set_flags(SystemLog::PANIC); /// display informacion ... fprintf(stderr, "\n%s\nCPU: %d, Reason: %s\n", panic_signature, current_cpu, why); // crash context (can help determine source of crash) const int len = strnlen(get_crash_context_buffer(), get_crash_context_length()); if (len > 0) { printf("\n\t**** CPU %d CONTEXT: ****\n %*s\n\n", current_cpu, len, get_crash_context_buffer()); } // heap info typedef unsigned long ulong; uintptr_t heap_total = OS::heap_max() - heap_begin; fprintf(stderr, "Heap is at: %p / %p (diff=%lu)\n", (void*) heap_end, (void*) OS::heap_max(), (ulong) (OS::heap_max() - heap_end)); fprintf(stderr, "Heap usage: %lu / %lu Kb\n", // (%.2f%%)\n", (ulong) (heap_end - heap_begin) / 1024, (ulong) heap_total / 1024); //, total * 100.0); print_backtrace(); fflush(stderr); SMP::global_unlock(); // action that restores some system functionality intended for inspection // NB: Don't call this from double faults panic_perform_inspection_procedure(); panic_epilogue(why); }