diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4 index 6f7412e42061..ce8f3776157a 100644 --- a/share/man/man4/ddb.4 +++ b/share/man/man4/ddb.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 29, 2008 +.Dd May 24, 2010 .Dt DDB 4 .Os .Sh NAME @@ -1092,9 +1092,13 @@ for a list of signals. Note that the arguments are reversed relative to .Xr kill 2 . .Pp -.It Ic reboot -.It Ic reset +.It Ic reboot Op Ar seconds +.It Ic reset Op Ar seconds Hard reset the system. +If the optional argument +.Ar seconds +is given, the debugger will wait for this long, at most a week, +before rebooting. .Pp .It Ic help Print a short summary of the available commands and command diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 73de0c502405..7c7f54e3702d 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -661,13 +661,42 @@ db_kill(dummy1, dummy2, dummy3, dummy4) #undef DB_ERROR } +/* + * Reboot. In case there is an additional argument, take it as delay in + * seconds. Default to 15s if we cannot parse it and make sure we will + * never wait longer than 1 week. Some code is similar to + * kern_shutdown.c:shutdown_panic(). + */ +#ifndef DB_RESET_MAXDELAY +#define DB_RESET_MAXDELAY (3600 * 24 * 7) +#endif + static void -db_reset(dummy1, dummy2, dummy3, dummy4) - db_expr_t dummy1; - boolean_t dummy2; - db_expr_t dummy3; - char * dummy4; +db_reset(db_expr_t addr, boolean_t have_addr, db_expr_t count __unused, + char *modif __unused) { + int delay, loop; + + if (have_addr) { + delay = (int)db_hex2dec(addr); + + /* If we parse to fail, use 15s. */ + if (delay == -1) + delay = 15; + + /* Cap at one week. */ + if ((uintmax_t)delay > (uintmax_t)DB_RESET_MAXDELAY) + delay = DB_RESET_MAXDELAY; + + db_printf("Automatic reboot in %d seconds - " + "press a key on the console to abort\n", delay); + for (loop = delay * 10; loop > 0; --loop) { + DELAY(1000 * 100); /* 1/10th second */ + /* Did user type a key? */ + if (cncheckc() != -1) + return; + } + } cpu_reset(); } @@ -771,3 +800,28 @@ db_stack_trace_all(db_expr_t dummy, boolean_t dummy2, db_expr_t dummy3, kdb_jmpbuf(prev_jb); } } + +/* + * Take the parsed expression value from the command line that was parsed + * as a hexadecimal value and convert it as if the expression was parsed + * as a decimal value. Returns -1 if the expression was not a valid + * decimal value. + */ +db_expr_t +db_hex2dec(db_expr_t expr) +{ + uintptr_t x, y; + db_expr_t val; + + y = 1; + val = 0; + x = expr; + while (x != 0) { + if (x % 16 > 9) + return (-1); + val += (x % 16) * (y); + x >>= 4; + y *= 10; + } + return (val); +} diff --git a/sys/ddb/db_command.h b/sys/ddb/db_command.h index 7d9370c254cf..2103a02ae99c 100644 --- a/sys/ddb/db_command.h +++ b/sys/ddb/db_command.h @@ -33,6 +33,12 @@ * Author: David B. Golub, Carnegie Mellon University * Date: 7/90 */ + +/* + * Helper functions. + */ +db_expr_t db_hex2dec(db_expr_t expr); + /* * Command loop declarations. */ diff --git a/sys/ddb/db_thread.c b/sys/ddb/db_thread.c index bf59f680b668..8ddb24066e81 100644 --- a/sys/ddb/db_thread.c +++ b/sys/ddb/db_thread.c @@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$"); #include #include -static db_expr_t hex2dec(db_expr_t expr); - void db_print_thread(void) { @@ -107,31 +105,6 @@ db_show_threads(db_expr_t addr, boolean_t hasaddr, db_expr_t cnt, char *mod) } } -/* - * Take the parsed expression value from the command line that was parsed - * as a hexadecimal value and convert it as if the expression was parsed - * as a decimal value. Returns -1 if the expression was not a valid - * decimal value. - */ -static db_expr_t -hex2dec(db_expr_t expr) -{ - uintptr_t x, y; - db_expr_t val; - - y = 1; - val = 0; - x = expr; - while (x != 0) { - if (x % 16 > 9) - return (-1); - val += (x % 16) * (y); - x >>= 4; - y *= 10; - } - return (val); -} - /* * Lookup a thread based on a db expression address. We assume that the * address was parsed in hexadecimal. We reparse the address in decimal @@ -151,7 +124,7 @@ db_lookup_thread(db_expr_t addr, boolean_t check_pid) * If the parsed address was not a valid decimal expression, * assume it is a thread pointer. */ - decaddr = hex2dec(addr); + decaddr = db_hex2dec(addr); if (decaddr == -1) return ((struct thread *)addr); @@ -183,7 +156,7 @@ db_lookup_proc(db_expr_t addr) db_expr_t decaddr; struct proc *p; - decaddr = hex2dec(addr); + decaddr = db_hex2dec(addr); if (decaddr != -1) { FOREACH_PROC_IN_SYSTEM(p) { if (p->p_pid == decaddr)