tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: diff: add show proc command to ddb
On 15:45 Wed 06 Apr, Eduardo Horvath wrote:
> On Wed, 6 Apr 2011, Vladimir Kirillov wrote:
>
> > Hello, tech-kern@!
> >
> > I really wanted a show proc command to avoid looking up process
> > information by running ps with all flags and intensive scrolling.
> >
> > The show proc output mostly combines the outputs of all switches
> > in ps.
>
> Neat!
>
> Since you're doing a lot of DDB rototilling, could you add an option to
> your 'show proc' command that also dumps each lwp's stacktrace? I find
> that extremly useful for diagnosing deadlocks. (The version I hacked up
> is not very clean.)
>
> Eduardo
show proc /t will do the trick.
Index: db_command.c
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_command.c,v
retrieving revision 1.134
diff -u -p -r1.134 db_command.c
--- db_command.c 13 Sep 2010 08:42:04 -0000 1.134
+++ db_command.c 7 Apr 2011 00:07:11 -0000
@@ -219,10 +219,12 @@ static const struct db_command db_show_c
#endif
{ DDB_ADD_CMD("pages", db_show_all_pages,
0 ,"List all used memory pages.",NULL,NULL) },
+ { DDB_ADD_CMD("proc", db_show_proc,
+ 0 ,"Print process information.",NULL,NULL) },
{ DDB_ADD_CMD("procs", db_show_all_procs,
0 ,"List all processes.",NULL,NULL) },
{ DDB_ADD_CMD("pools", db_show_all_pools,
- 0 ,"Show all poolS",NULL,NULL) },
+ 0 ,"Show all pools",NULL,NULL) },
#ifdef AIO
/*added from all sub cmds*/
{ DDB_ADD_CMD("aio_jobs", db_show_aio_jobs, 0,
Index: db_interface.h
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_interface.h,v
retrieving revision 1.25
diff -u -p -r1.25 db_interface.h
--- db_interface.h 18 Feb 2009 13:31:59 -0000 1.25
+++ db_interface.h 7 Apr 2011 00:07:11 -0000
@@ -46,6 +46,7 @@ void db_show_files_cmd(db_expr_t, bool,
/* kern/kern_proc.c */
void db_kill_proc(db_expr_t, bool, db_expr_t, const char *);
+void db_show_proc(db_expr_t, bool, db_expr_t, const char *);
void db_show_all_procs(db_expr_t, bool, db_expr_t, const char *);
void db_show_all_pools(db_expr_t, bool, db_expr_t, const char *);
void db_show_sched_qs(db_expr_t, bool, db_expr_t, const char *);
Index: db_proc.c
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_proc.c,v
retrieving revision 1.3
diff -u -p -r1.3 db_proc.c
--- db_proc.c 9 Mar 2009 06:07:05 -0000 1.3
+++ db_proc.c 7 Apr 2011 00:07:11 -0000
@@ -129,8 +129,8 @@ db_show_all_procs(db_expr_t addr, bool h
if (mode == NULL || *mode == 'm') {
db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n");
db_printf("\t/a == show process address info\n");
- db_printf("\t/l == show LWP info\n");
- db_printf("\t/n == show normal process info [default]\n");
+ db_printf("\t/l == show LWP info [default]\n");
+ db_printf("\t/n == show normal process info\n");
db_printf("\t/w == show process wait/emul info\n");
return;
}
@@ -257,3 +257,99 @@ db_show_all_procs(db_expr_t addr, bool h
}
}
+void
+db_show_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
+{
+ static proc_t p;
+ static lwp_t l;
+ const char *mode, *modifp;
+ bool stacktrace;
+ proc_t *pp;
+ lwp_t *lp;
+ char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
+ bool run;
+ int cpuno;
+
+ modifp = modif;
+ mode = NULL;
+ stacktrace = false;
+
+ while (*modifp) {
+ if (mode == NULL)
+ mode = strchr("ap", *modifp);
+ if (stacktrace == false)
+ stacktrace = *modifp == 't';
+ modifp++;
+ }
+ if (mode == NULL)
+ mode = "p"; /* default == by pid */
+
+ if (haddr == false) {
+ db_printf("usage: show proc [/apt] address|pid\n");
+ db_printf("\t/a == argument is an address of any lwp\n");
+ db_printf("\t/p == argument is a pid [default]\n");
+ db_printf("\t/t == dump the stack of each lwp\n");
+ return;
+ }
+
+ switch (*mode) {
+ case 'a':
+ db_read_bytes((db_addr_t)addr, sizeof(l), (char *)&l);
+ pp = l.l_proc;
+ break;
+ case 'p':
+ default:
+ pp = db_proc_find((pid_t)addr);
+ break;
+ }
+
+ if (pp == NULL) {
+ db_printf("bad address\n");
+ return;
+ }
+
+ db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
+ lp = p.p_lwps.lh_first;
+
+ db_printf("%s: pid %d proc %lx vmspace/map %lx flags %x\n",
+ p.p_comm, p.p_pid, (long)pp, (long)p.p_vmspace, p.p_flag);
+
+ while (lp != NULL) {
+ db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
+
+ run = (l.l_stat == LSONPROC ||
+ (l.l_pflag & LP_RUNNING) != 0);
+
+ db_printf("%slwp %d", (run ? "> " : " "), l.l_lid);
+ if (l.l_name != NULL) {
+ db_read_bytes((db_addr_t)l.l_name,
+ MAXCOMLEN, db_nbuf);
+ db_printf(" [%s]", db_nbuf);
+ }
+ db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr);
+
+ if (l.l_cpu != NULL) {
+ db_read_bytes((db_addr_t)
+ &l.l_cpu->ci_data.cpu_index,
+ sizeof(cpuno), (char *)&cpuno);
+ } else
+ cpuno = -1;
+ db_printf(" stat %d flags %x cpu %d pri %d \n",
+ l.l_stat, l.l_flag, cpuno, l.l_priority);
+
+ if (l.l_wchan && l.l_wmesg) {
+ db_read_bytes((db_addr_t)l.l_wmesg,
+ sizeof(wbuf), (char *)wbuf);
+ db_printf(" wmesg %s wchan %lx\n",
+ wbuf, (long)l.l_wchan);
+ }
+
+ if (stacktrace) {
+ db_stack_trace_print((db_addr_t)lp, true, 65535, "a",
+ db_printf);
+ db_printf("\n");
+ }
+
+ lp = LIST_NEXT(&l, l_sibling);
+ }
+}
Home |
Main Index |
Thread Index |
Old Index