Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_shutdown.c
| Show First 20 Lines • Show All 798 Lines • ▼ Show 20 Lines | if (error == 0) { | ||||
| error = sysctl_handle_int(oidp, &i, 0, req); | error = sysctl_handle_int(oidp, &i, 0, req); | ||||
| } | } | ||||
| if (error != 0 || req->newptr == NULL) | if (error != 0 || req->newptr == NULL) | ||||
| return (error); | return (error); | ||||
| KASSERT(0, ("kassert_sysctl_kassert triggered kassert %d", i)); | KASSERT(0, ("kassert_sysctl_kassert triggered kassert %d", i)); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| static const char * | |||||
| trim_to_sys(const char *path) | |||||
| { | |||||
| const char *tp, *cp = path; | |||||
| while ((tp = strstr(cp, "/sys/")) != NULL ) { | |||||
| cp = tp + 1; | |||||
| } | |||||
| return (cp); | |||||
| } | |||||
| static void | |||||
| panic_print_location(const struct panic_codeptr *where) | |||||
| { | |||||
| #if !defined(KASSERT_PANIC_NOCONTEXT) | |||||
| printf(" at %s:%d (%s)", trim_to_sys(where->fname), where->linen, | |||||
| where->funcn); | |||||
| #else | |||||
| (void)where; | |||||
| #endif | |||||
| } | |||||
| #ifdef KASSERT_PANIC_OPTIONAL | #ifdef KASSERT_PANIC_OPTIONAL | ||||
| static void | |||||
| kassert_print(const struct panic_codeptr *where, const char *buf) | |||||
| { | |||||
| printf("KASSERT failed: %s", buf); | |||||
| panic_print_location(where); | |||||
| printf("\n"); | |||||
| } | |||||
| /* | /* | ||||
| * Called by KASSERT, this decides if we will panic | * Called by KASSERT, this decides if we will panic | ||||
| * or if we will log via printf and/or ktr. | * or if we will log via printf and/or ktr. | ||||
| */ | */ | ||||
| void | void | ||||
| kassert_panic(const char *fmt, ...) | do_kassert_panic(const struct panic_codeptr *where, const char *fmt, ...) | ||||
| { | { | ||||
| static char buf[256]; | static char buf[256]; | ||||
| va_list ap; | va_list ap; | ||||
| va_start(ap, fmt); | va_start(ap, fmt); | ||||
| (void)vsnprintf(buf, sizeof(buf), fmt, ap); | (void)vsnprintf(buf, sizeof(buf), fmt, ap); | ||||
| va_end(ap); | va_end(ap); | ||||
| /* | /* | ||||
| * If we are suppressing secondary panics, log the warning but do not | * If we are suppressing secondary panics, log the warning but do not | ||||
| * re-enter panic/kdb. | * re-enter panic/kdb. | ||||
| */ | */ | ||||
| if (KERNEL_PANICKED() && kassert_suppress_in_panic) { | if (KERNEL_PANICKED() && kassert_suppress_in_panic) { | ||||
| if (kassert_do_log) { | if (kassert_do_log) { | ||||
| printf("KASSERT failed: %s\n", buf); | kassert_print(where, buf); | ||||
| #ifdef KDB | #ifdef KDB | ||||
| if (trace_all_panics && trace_on_panic) | if (trace_all_panics && trace_on_panic) | ||||
| kdb_backtrace(); | kdb_backtrace(); | ||||
| #endif | #endif | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| /* | /* | ||||
| * panic if we're not just warning, or if we've exceeded | * panic if we're not just warning, or if we've exceeded | ||||
| * kassert_log_panic_at warnings. | * kassert_log_panic_at warnings. | ||||
| */ | */ | ||||
| if (!kassert_warn_only || | if (!kassert_warn_only || | ||||
| (kassert_log_panic_at > 0 && | (kassert_log_panic_at > 0 && | ||||
| kassert_warnings >= kassert_log_panic_at)) { | kassert_warnings >= kassert_log_panic_at)) { | ||||
| va_start(ap, fmt); | va_start(ap, fmt); | ||||
| vpanic(fmt, ap); | do_vpanic(where, fmt, ap); | ||||
| /* NORETURN */ | /* NORETURN */ | ||||
| } | } | ||||
| #ifdef KTR | #ifdef KTR | ||||
| if (kassert_do_ktr) | if (kassert_do_ktr) | ||||
| CTR0(ktr_mask, buf); | CTR0(ktr_mask, buf); | ||||
| #endif /* KTR */ | #endif /* KTR */ | ||||
| /* | /* | ||||
| * log if we've not yet met the mute limit. | * log if we've not yet met the mute limit. | ||||
| */ | */ | ||||
| if (kassert_do_log && | if (kassert_do_log && | ||||
| (kassert_log_mute_at == 0 || | (kassert_log_mute_at == 0 || | ||||
| kassert_warnings < kassert_log_mute_at)) { | kassert_warnings < kassert_log_mute_at)) { | ||||
| static struct timeval lasterr; | static struct timeval lasterr; | ||||
| static int curerr; | static int curerr; | ||||
| if (ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) { | if (ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) { | ||||
| printf("KASSERT failed: %s\n", buf); | kassert_print(where, buf); | ||||
| kdb_backtrace(); | kdb_backtrace(); | ||||
| } | } | ||||
| } | } | ||||
| #ifdef KDB | #ifdef KDB | ||||
| if (kassert_do_kdb) { | if (kassert_do_kdb) { | ||||
| kdb_enter(KDB_WHY_KASSERT, buf); | kdb_enter(KDB_WHY_KASSERT, buf); | ||||
| } | } | ||||
| #endif | #endif | ||||
| atomic_add_int(&kassert_warnings, 1); | atomic_add_int(&kassert_warnings, 1); | ||||
| } | } | ||||
| #endif /* KASSERT_PANIC_OPTIONAL */ | #endif /* KASSERT_PANIC_OPTIONAL */ | ||||
| #endif | #endif | ||||
| /* | /* | ||||
| * Panic is called on unresolvable fatal errors. It prints "panic: mesg", | * Panic is called on unresolvable fatal errors. It prints "panic: mesg" | ||||
| * and then reboots. If we are called twice, then we avoid trying to sync | * and any available source-location context, and then reboots. If we are | ||||
| * the disks as this often leads to recursive panics. | * called twice, then we avoid trying to sync the disks as this often leads | ||||
| * to recursive panics. | |||||
| */ | */ | ||||
| void | void | ||||
| panic(const char *fmt, ...) | do_panic(const struct panic_codeptr *where, const char *fmt, ...) | ||||
| { | { | ||||
| va_list ap; | va_list ap; | ||||
| va_start(ap, fmt); | va_start(ap, fmt); | ||||
| vpanic(fmt, ap); | do_vpanic(where, fmt, ap); | ||||
| } | } | ||||
| void | void | ||||
| vpanic(const char *fmt, va_list ap) | do_vpanic(const struct panic_codeptr *where, const char *fmt, va_list ap) | ||||
| { | { | ||||
| #ifdef SMP | #ifdef SMP | ||||
| cpuset_t other_cpus; | cpuset_t other_cpus; | ||||
| #endif | #endif | ||||
| struct thread *td = curthread; | struct thread *td = curthread; | ||||
| int bootopt, newpanic; | int bootopt, newpanic; | ||||
| static char buf[256]; | static char buf[256]; | ||||
| Show All 35 Lines | else { | ||||
| bootopt |= RB_DUMP; | bootopt |= RB_DUMP; | ||||
| panicstr = fmt; | panicstr = fmt; | ||||
| newpanic = 1; | newpanic = 1; | ||||
| } | } | ||||
| /* Unmute when panic */ | /* Unmute when panic */ | ||||
| cn_mute = 0; | cn_mute = 0; | ||||
| if (newpanic) | |||||
| cngrab(); | |||||
| if (newpanic) { | if (newpanic) { | ||||
| (void)vsnprintf(buf, sizeof(buf), fmt, ap); | (void)vsnprintf(buf, sizeof(buf), fmt, ap); | ||||
| panicstr = buf; | panicstr = buf; | ||||
| cngrab(); | printf("panic: %s", buf); | ||||
| printf("panic: %s\n", buf); | |||||
| } else { | } else { | ||||
| printf("panic: "); | printf("panic: "); | ||||
| vprintf(fmt, ap); | vprintf(fmt, ap); | ||||
| printf("\n"); | |||||
| } | } | ||||
| panic_print_location(where); | |||||
| printf("\n"); | |||||
| #ifdef SMP | #ifdef SMP | ||||
| printf("cpuid = %d\n", PCPU_GET(cpuid)); | printf("cpuid = %d\n", PCPU_GET(cpuid)); | ||||
| #endif | #endif | ||||
| printf("time = %jd\n", (intmax_t )time_second); | printf("time = %jd\n", (intmax_t )time_second); | ||||
| #ifdef KDB | #ifdef KDB | ||||
| if ((newpanic || trace_all_panics) && trace_on_panic) | if ((newpanic || trace_all_panics) && trace_on_panic) | ||||
| kdb_backtrace(); | kdb_backtrace(); | ||||
| if (debugger_on_panic) | if (debugger_on_panic) | ||||
| ▲ Show 20 Lines • Show All 877 Lines • Show Last 20 Lines | |||||