[PATCH] PPC64: xmon: add process-display command

Linas Vepstas linas at austin.ibm.com
Fri Sep 24 07:19:14 EST 2004



Hi,

The following patch adds process display to xmon.   
The current xmon does have a process display, but it 
has several problems:
1) it displays nothing if the logging level isn't set; 
    and xmon doesn't currently support sysreq commands.
2) if it can be made to display, then it would display 
    stacks too, which is waaaay too much if one has
    hundreds of processes.
3) it depends on code that uses uses spinlocks :(
4) it fails to validate any pointers it chases. 

The attached patch fixes all but 4): it prints a short-form
process display with the little 'p' command, and a long form, 
with stacks, with the big 'P' command.

Please forward and apply ... 

Signed-off-by: Linas Vepstas <linas at linas.org>

--linas
-------------- next part --------------
--- gidyap/arch/ppc64/xmon/xmon.c	Mon Sep 13 19:23:15 2004
+++ edited/arch/ppc64/xmon/xmon.c	Thu Sep 23 13:26:14 2004
@@ -193,6 +193,7 @@ Commands:\n\
   mz	zero a block of memory\n\
   mi	show information about memory allocation\n\
   p 	show the task list\n\
+  P 	show the task list and stacks\n\
   r	print registers\n\
   s	single step\n\
   S	print special registers\n\
@@ -881,6 +882,81 @@ static inline struct task_struct *younge
 	return list_entry(p->sibling.next,struct task_struct,sibling);
 }
 
+static void xmon_show_task(task_t * p, int prt_stacks)
+{
+	task_t *relative;
+	unsigned state;
+	unsigned long free = 0;
+	static const char *stat_nam[] = { "R", "S", "D", "T", "t", "Z", "X" };
+
+	printf("%-13.13s ", p->comm);
+	state = p->state ? __ffs(p->state) + 1 : 0;
+	if (state < ARRAY_SIZE(stat_nam))
+		printf(stat_nam[state]);
+	else
+		printf("?");
+#if (BITS_PER_LONG == 32)
+	if (state == TASK_RUNNING)
+		printf(" running ");
+	else
+		printf(" %08lX ", thread_saved_pc(p));
+#else
+	if (state == TASK_RUNNING)
+		printf("  running task   ");
+	else
+		printf(" %016lx ", thread_saved_pc(p));
+#endif
+#ifdef CONFIG_DEBUG_STACK_USAGE
+	{
+		unsigned long * n = (unsigned long *) (p->thread_info+1);
+		while (!*n)
+			n++;
+		free = (unsigned long) n - (unsigned long)(p->thread_info+1);
+	}
+#endif
+	printf("%5lu %5d %6d ", free, p->pid, p->parent->pid);
+	if ((relative = eldest_child(p)))
+		printf("%5d ", relative->pid);
+	else
+		printf("      ");
+	if ((relative = younger_sibling(p)))
+		printf("%7d", relative->pid);
+	else
+		printf("       ");
+	if ((relative = older_sibling(p)))
+		printf(" %5d", relative->pid);
+	else
+		printf("      ");
+	if (!p->mm)
+		printf(" (L-TLB)\n");
+	else
+		printf(" (NOTLB)\n");
+
+	if (prt_stacks)
+		show_stack(p, NULL);
+}
+
+static task_t *xmon_next_thread(const task_t *p) 
+{
+	return pid_task(p->pids[PIDTYPE_TGID].pid_list.next, PIDTYPE_TGID);
+}
+
+static void xmon_show_state(int prt_stacks)
+{
+	task_t *g, *p;
+#if (BITS_PER_LONG == 32)
+	printf("\n"
+	       "                                               sibling\n");
+	printf("  task             PC      pid father child younger older\n");
+#else
+	printf("\n"
+		    "                                                       sibling\n");
+	printf("  task                 PC          pid father child younger older\n");
+#endif
+	do_each_thread(g, p) {
+		xmon_show_task(p, prt_stacks);
+	} while ((p = xmon_next_thread(p)) != g);
+}
 
 /* Command interpreting routine */
 static char *last_cmd;
@@ -967,7 +1043,10 @@ cmds(struct pt_regs *excp)
 			printf(help_string);
 			break;
 		case 'p':
-			show_state();
+			xmon_show_state(0);
+			break;
+		case 'P':
+			xmon_show_state(1);
 			break;
 		case 'b':
 			bpt_cmds();


More information about the Linuxppc64-dev mailing list