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

Linas Vepstas linas at austin.ibm.com
Thu Sep 30 03:04:51 EST 2004


Hi,

The following patch adds process display to xmon. 
It supreseeds the previous patch I sent in for this
(http://ozlabs.org/ppc64-patches/patch.pl?id=306)

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

The attached patch fixes all but 5): 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 
-------------- next part --------------
--- bk/arch/ppc64/xmon/xmon.c.	2004-09-29 11:10:43.000000000 -0500
+++ edited/arch/ppc64/xmon/xmon.c	2004-09-29 11:52:28.000000000 -0500
@@ -2,6 +2,9 @@
  * Routines providing a simple monitor for use on the PowerMac.
  *
  * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 1999-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2000 Stephane Eranian <eranian at hpl.hp.com>
+ * Xscale (R) modifications copyright (C) 2003 Intel Corporation.
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -13,6 +16,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
+#include <linux/ptrace.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/kallsyms.h>
@@ -101,6 +105,7 @@ static void prdump(unsigned long, long);
 static int ppc_inst_dump(unsigned long, long, int);
 void print_address(unsigned long);
 static void backtrace(struct pt_regs *);
+static void xmon_show_stack(unsigned long sp, unsigned long lr, unsigned long pc);
 static void excprint(struct pt_regs *);
 static void prregs(struct pt_regs *);
 static void memops(int);
@@ -193,6 +198,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\
@@ -861,6 +867,63 @@ static int emulate_step(struct pt_regs *
 	return 0;
 }
 
+static inline int 
+xmon_process_cpu(const task_t *p)
+{
+	return p->thread_info->cpu;
+}
+
+#define xmon_task_has_cpu(p) (task_curr(p))
+
+static void
+xmon_show_task(task_t *p)
+{
+	printf("0x%p %8d %8d  %d %4d   %c  0x%p %c%s\n",
+		   (void *)p, p->pid, p->parent->pid,
+		   xmon_task_has_cpu(p), xmon_process_cpu(p),
+		   (p->state == 0) ? 'R' :
+		     (p->state < 0) ? 'U' :
+		     (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+		     (p->state & TASK_STOPPED || p->ptrace & PT_PTRACED) ? 'T' :
+		     (p->state & TASK_ZOMBIE) ? 'Z' :
+		     (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?',
+		   (void *)(&p->thread),
+		   (p == current) ? '*': ' ',
+		   p->comm);
+}
+
+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;
+
+	printf("%-*s      Pid   Parent [*] cpu State %-*s Command\n",
+		(int)(2*sizeof(void *))+2, "Task Addr",
+		(int)(2*sizeof(void *))+2, "Thread");
+
+#ifdef PER_CPU_RUNQUEUES_NO_LONGER_DECLARED_STATIC_IN_SCHED_C
+	/* Run the active tasks first */
+	for (cpu = 0; cpu < NR_CPUS; ++cpu) 
+		if (cpu_online(cpu)) {
+			p = cpu_curr(cpu);
+			xmon_show_task(p);
+		}
+#endif
+
+	/* Now the real tasks */
+	do_each_thread(g, p) {
+		xmon_show_task(p);
+		if (prt_stacks) 
+			xmon_show_stack(p->thread.ksp, 0, 0);
+	} while ((p = xmon_next_thread(p)) != g);
+}
+
+
 /* Command interpreting routine */
 static char *last_cmd;
 
@@ -946,7 +1009,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