svn commit: r208509 - in head: share/man/man4 sys/ddb

Bjoern A. Zeeb bz at FreeBSD.org
Mon May 24 16:41:06 UTC 2010


Author: bz
Date: Mon May 24 16:41:05 2010
New Revision: 208509
URL: http://svn.freebsd.org/changeset/base/208509

Log:
  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

Modified:
  head/share/man/man4/ddb.4
  head/sys/ddb/db_command.c
  head/sys/ddb/db_command.h
  head/sys/ddb/db_thread.c

Modified: head/share/man/man4/ddb.4
==============================================================================
--- head/share/man/man4/ddb.4	Mon May 24 16:27:47 2010	(r208508)
+++ head/share/man/man4/ddb.4	Mon May 24 16:41:05 2010	(r208509)
@@ -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

Modified: head/sys/ddb/db_command.c
==============================================================================
--- head/sys/ddb/db_command.c	Mon May 24 16:27:47 2010	(r208508)
+++ head/sys/ddb/db_command.c	Mon May 24 16:41:05 2010	(r208509)
@@ -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, bool
 		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);
+}

Modified: head/sys/ddb/db_command.h
==============================================================================
--- head/sys/ddb/db_command.h	Mon May 24 16:27:47 2010	(r208508)
+++ head/sys/ddb/db_command.h	Mon May 24 16:41:05 2010	(r208509)
@@ -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.
  */

Modified: head/sys/ddb/db_thread.c
==============================================================================
--- head/sys/ddb/db_thread.c	Mon May 24 16:27:47 2010	(r208508)
+++ head/sys/ddb/db_thread.c	Mon May 24 16:41:05 2010	(r208509)
@@ -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_
 }
 
 /*
- * 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
 	 * 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)


More information about the svn-src-all mailing list