Lately I had to debug a problem where a kernel bug resulted in CPU
exhaustion. When this happens there's nothing to do but reboot the
machine via ddb(4).
Today I'm facing a similar problem. Sadly rebooting doesn't help
to debug the issue. And since ddb(4) doesn't know (yet) how to
display userland traces, I don't learn much from a freeze.
That's why I'd like to introduce a new ddb(4) command: kill. This
command use the same trick as pledge(2), it sends and uncatchable
SIGABRT. This is enough for me to kill the process DoSing my machine,
lldpd(8) in my case, and inspect its coredump.
ok?
Index: sys/ddb/db_command.c
===================================================================
RCS file: /cvs/src/sys/ddb/db_command.c,v
retrieving revision 1.77
diff -u -p -r1.77 db_command.c
--- sys/ddb/db_command.c 12 Sep 2017 08:23:42 -0000 1.77
+++ sys/ddb/db_command.c 28 Sep 2017 12:47:54 -0000
@@ -612,6 +612,7 @@ struct db_command db_command_table[] = {
/* this must be the first entry, if it exists */
{ "machine", NULL, 0, NULL},
#endif
+ { "kill", db_kill_cmd, 0, NULL },
{ "print", db_print_cmd, 0, NULL },
{ "p", db_print_cmd, 0, NULL },
{ "pprint", db_ctf_pprint_cmd, CS_OWN, NULL },
Index: sys/ddb/db_interface.h
===================================================================
RCS file: /cvs/src/sys/ddb/db_interface.h,v
retrieving revision 1.19
diff -u -p -r1.19 db_interface.h
--- sys/ddb/db_interface.h 9 Jan 2017 17:58:44 -0000 1.19
+++ sys/ddb/db_interface.h 28 Sep 2017 12:47:54 -0000
@@ -40,6 +40,7 @@ void db_stack_trace_print(db_expr_t, int
db_addr_t db_disasm(db_addr_t, boolean_t);
/* kern/kern_proc.c */
+void db_kill_cmd(db_expr_t, int, db_expr_t, char *);
void db_show_all_procs(db_expr_t, int, db_expr_t, char *);
/* kern/kern_timeout.c */
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.76
diff -u -p -r1.76 kern_proc.c
--- sys/kern/kern_proc.c 4 Feb 2017 07:42:52 -0000 1.76
+++ sys/kern/kern_proc.c 28 Sep 2017 12:47:54 -0000
@@ -440,6 +440,28 @@ proc_printit(struct proc *p, const char
#include <ddb/db_output.h>
void
+db_kill_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
+{
+ struct process *pr;
+ struct sigaction sa;
+ struct proc *p;
+
+ pr = prfind(addr);
+ if (pr == NULL) {
+ db_printf("%ld: No such process", addr);
+ return;
+ }
+
+ p = TAILQ_FIRST(&pr->ps_threads);
+
+ /* Send uncatchable SIGABRT for coredump */
+ memset(&sa, 0, sizeof sa);
+ sa.sa_handler = SIG_DFL;
+ setsigvec(p, SIGABRT, &sa);
+ psignal(p, SIGABRT);
+}
+
+void
db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
{
char *mode;
Index: share/man/man4/ddb.4
===================================================================
RCS file: /cvs/src/share/man/man4/ddb.4,v
retrieving revision 1.90
diff -u -p -r1.90 ddb.4
--- share/man/man4/ddb.4 12 Sep 2017 08:27:44 -0000 1.90
+++ share/man/man4/ddb.4 28 Sep 2017 12:53:37 -0000
@@ -542,6 +542,13 @@ The
command is a synonym for
.Ic match .
.\" --------------------
+.It Ic kill Ar pid
+Send an uncatchable
+.Dv SIGABRT
+signal to the process specified by the
+.Ar pid
+argument.
+.\" --------------------
.It Xo
.Ic trace
.Op Cm /pu