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
This commit is contained in:
parent
3abaa08643
commit
0f59fbc3d6
@ -60,7 +60,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 29, 2008
|
.Dd May 24, 2010
|
||||||
.Dt DDB 4
|
.Dt DDB 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -1092,9 +1092,13 @@ for a list of signals.
|
|||||||
Note that the arguments are reversed relative to
|
Note that the arguments are reversed relative to
|
||||||
.Xr kill 2 .
|
.Xr kill 2 .
|
||||||
.Pp
|
.Pp
|
||||||
.It Ic reboot
|
.It Ic reboot Op Ar seconds
|
||||||
.It Ic reset
|
.It Ic reset Op Ar seconds
|
||||||
Hard reset the system.
|
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
|
.Pp
|
||||||
.It Ic help
|
.It Ic help
|
||||||
Print a short summary of the available commands and command
|
Print a short summary of the available commands and command
|
||||||
|
@ -661,13 +661,42 @@ db_kill(dummy1, dummy2, dummy3, dummy4)
|
|||||||
#undef DB_ERROR
|
#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
|
static void
|
||||||
db_reset(dummy1, dummy2, dummy3, dummy4)
|
db_reset(db_expr_t addr, boolean_t have_addr, db_expr_t count __unused,
|
||||||
db_expr_t dummy1;
|
char *modif __unused)
|
||||||
boolean_t dummy2;
|
|
||||||
db_expr_t dummy3;
|
|
||||||
char * dummy4;
|
|
||||||
{
|
{
|
||||||
|
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();
|
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);
|
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);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,12 @@
|
|||||||
* Author: David B. Golub, Carnegie Mellon University
|
* Author: David B. Golub, Carnegie Mellon University
|
||||||
* Date: 7/90
|
* Date: 7/90
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper functions.
|
||||||
|
*/
|
||||||
|
db_expr_t db_hex2dec(db_expr_t expr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command loop declarations.
|
* Command loop declarations.
|
||||||
*/
|
*/
|
||||||
|
@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <ddb/db_command.h>
|
#include <ddb/db_command.h>
|
||||||
#include <ddb/db_sym.h>
|
#include <ddb/db_sym.h>
|
||||||
|
|
||||||
static db_expr_t hex2dec(db_expr_t expr);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
db_print_thread(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
|
* Lookup a thread based on a db expression address. We assume that the
|
||||||
* address was parsed in hexadecimal. We reparse the address in decimal
|
* 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,
|
* If the parsed address was not a valid decimal expression,
|
||||||
* assume it is a thread pointer.
|
* assume it is a thread pointer.
|
||||||
*/
|
*/
|
||||||
decaddr = hex2dec(addr);
|
decaddr = db_hex2dec(addr);
|
||||||
if (decaddr == -1)
|
if (decaddr == -1)
|
||||||
return ((struct thread *)addr);
|
return ((struct thread *)addr);
|
||||||
|
|
||||||
@ -183,7 +156,7 @@ db_lookup_proc(db_expr_t addr)
|
|||||||
db_expr_t decaddr;
|
db_expr_t decaddr;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
decaddr = hex2dec(addr);
|
decaddr = db_hex2dec(addr);
|
||||||
if (decaddr != -1) {
|
if (decaddr != -1) {
|
||||||
FOREACH_PROC_IN_SYSTEM(p) {
|
FOREACH_PROC_IN_SYSTEM(p) {
|
||||||
if (p->p_pid == decaddr)
|
if (p->p_pid == decaddr)
|
||||||
|
Loading…
Reference in New Issue
Block a user