summaryrefslogtreecommitdiffstats
path: root/sys/ddb
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-05-24 16:41:05 +0000
committerbz <bz@FreeBSD.org>2010-05-24 16:41:05 +0000
commit6776200983bceda223944d82e99b820658ecd62b (patch)
treebdd087309119f3eab516764a7a8a1643c4691a2b /sys/ddb
parent36eb388782ebccd910604f919e2bd8f13cc05362 (diff)
downloadFreeBSD-src-6776200983bceda223944d82e99b820658ecd62b.zip
FreeBSD-src-6776200983bceda223944d82e99b820658ecd62b.tar.gz
MFp4 @178364:
Implement an optional delay to the ddb reset/reboot command. This allows textdumps to be run automatically with unattended reboots after a resonable timeout, while still permitting an administrator to break into debugger if attached to the console at the time of the event for further debugging. Cap the maximum delay at 1 week to avoid highly accidental results, and default to 15s in case of problems parsing the timeout value. Move hex2dec helper function from db_thread.c to db_command.c to make it generally available and prefix it with a "db_" to avoid namespace collisions. Reviewed by: rwatson MFC after: 4 weeks
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_command.c64
-rw-r--r--sys/ddb/db_command.h6
-rw-r--r--sys/ddb/db_thread.c31
3 files changed, 67 insertions, 34 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index 73de0c5..7c7f54e 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -661,13 +661,42 @@ out:
#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 7d9370c..2103a02 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 bf59f68..8ddb240 100644
--- a/sys/ddb/db_thread.c
+++ b/sys/ddb/db_thread.c
@@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_command.h>
#include <ddb/db_sym.h>
-static db_expr_t hex2dec(db_expr_t expr);
-
void
db_print_thread(void)
{
@@ -108,31 +106,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
* first and try to treat it as a thread ID to find an associated thread.
@@ -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)
OpenPOWER on IntegriCloud