--- crash-4.0-3.6/task.c	2006-10-05 21:43:10.000000000 +0200
+++ crash-4.0-3.6-patch/task.c	2006-10-06 19:46:08.000000000 +0200
@@ -16,7 +16,11 @@
  */
 
 #include "defs.h"
-
+#define TASK_LEVEL 1
+#define TASK_GROUP_LEVEL 2
+#define TASK_INDENT2 4
+#define CMD_PS 0
+#define CMD_SIG 1
 static ulong get_panic_context(void);
 static int sort_by_pid(const void *, const void *);
 static void show_ps(ulong, struct psinfo *);
@@ -34,7 +38,7 @@
 static void child_list(ulong);
 static void show_task_times(struct task_context *, ulong);
 static void show_task_args(struct task_context *);
-static void show_tgid_list(ulong);
+static void show_tgid_list(ulong,int);
 static int compare_start_time(const void *, const void *);
 static int start_time_timespec(void);
 static ulonglong convert_start_time(ulonglong, ulonglong);
@@ -51,7 +55,7 @@
 static void dump_prio_array(int, ulong, char *);
 static void task_struct_member(struct task_context *,ulong,struct reference *);
 static void signal_reference(struct task_context *, ulong, struct reference *);
-static void dump_signal_data(struct task_context *);
+static void dump_signal_data(struct task_context *, int);
 static int sigrt_minmax(int *, int *);
 static void signame_list(void);
 static void sigqueue_list(ulong);
@@ -2282,7 +2286,7 @@
                 continue;                                             \
         }                                                             \
         if (flag & PS_TGID_LIST) {                                    \
-                show_tgid_list(tc->task);                             \
+                show_tgid_list(tc->task,CMD_PS);                             \
                 continue;                                             \
         }                                                             \
         get_task_mem_usage(tc->task, tm);                             \
@@ -2911,7 +2915,7 @@
  *  Dump the children of a task.
  */
 static void
-show_tgid_list(ulong task)
+show_tgid_list(ulong task,int cmd)
 {
         int i;
         int cnt;
@@ -2933,7 +2937,13 @@
 	if ((tc->pid == 0) && (pc->curcmd_flags & IDLE_TASK_SHOWN))
 		return;
 
+	if (cmd & CMD_SIG) {
+		dump_signal_data(tc,TASK_GROUP_LEVEL);
+		fprintf(fp, "\n");
+	}
        	print_task_header(fp, tc, 0);
+	if (cmd & CMD_SIG) 
+		dump_signal_data(tc,TASK_LEVEL);
 
         tc = FIRST_CONTEXT();
         for (i = cnt = 0; i < RUNNING_TASKS(); i++, tc++) {
@@ -2941,8 +2951,13 @@
 			continue;
 
 		if (task_tgid(tc->task)	== tgid) {
+			if (cmd & CMD_SIG)
+				fprintf(fp, "\n");
                         INDENT(2);
                         print_task_header(fp, tc, 0);
+			if (cmd & CMD_SIG) {
+				dump_signal_data(tc,TASK_LEVEL|TASK_INDENT2);
+			}
                         cnt++;
 			if (tc->pid == 0)
 				pc->curcmd_flags |= IDLE_TASK_SHOWN;
@@ -2951,7 +2966,6 @@
 
         if (!cnt)
                 fprintf(fp, "  (no threads)\n");
-
 	fprintf(fp, "\n");
 }
 
@@ -5936,13 +5950,14 @@
 	struct task_context *tc;
 	ulong *tasklist;
 	char *siglist;
+	int task_group=FALSE;
 
 	tasklist = (ulong *)GETBUF((MAXARGS+NR_CPUS)*sizeof(ulong));
 	ref = (struct reference *)GETBUF(sizeof(struct reference));
 	siglist = GETBUF(BUFSIZE);
 	ref->str = siglist;
 
-        while ((c = getopt(argcnt, args, "lR:s:")) != EOF) {
+        while ((c = getopt(argcnt, args, "lR:s:g")) != EOF) {
                 switch(c)
 		{
 		case 's':
@@ -5959,7 +5974,9 @@
 		case 'l':
 			signame_list();
 			return;
-
+		case 'g':
+			task_group=TRUE;
+			break;
 		default:
 			argerrs++;
 			break;
@@ -6006,9 +6023,14 @@
 		tasklist[tcnt++] = CURRENT_TASK();
 
 	for (c = 0; c < tcnt; c++) {
+		if(task_group){
+			pc->curcmd_flags |= TASK_SPECIFIED;
+			show_tgid_list(tasklist[c],CMD_SIG);
+		} else {
 		do_sig(tasklist[c], 0, strlen(ref->str) ? ref : NULL);
 		fprintf(fp, "\n");
 	}
+	}
 
 }
 
@@ -6027,7 +6049,7 @@
         else {
                 if (!(flags & FOREACH_TASK))
                         print_task_header(fp, tc, 0);
-                dump_signal_data(tc);
+                dump_signal_data(tc,TASK_LEVEL|TASK_GROUP_LEVEL);
         }
 }
 
@@ -6047,7 +6069,7 @@
  *  Dump all signal-handling data for a task.
  */
 static void
-dump_signal_data(struct task_context *tc)
+dump_signal_data(struct task_context *tc, int task_flags)
 {
 	int i, sigrtmax, others, use_sighand;
 	int translate, sigpending;
@@ -6074,16 +6096,6 @@
 	sigset = task_signal(tc->task, 0);
 	if (!tt->last_task_read)
 		return;
-	blocked = task_blocked(tc->task);
-
-	if (VALID_MEMBER(task_struct_sigpending))
-		sigpending = INT(tt->task_struct + 
-			OFFSET(task_struct_sigpending));
-	else if (VALID_MEMBER(thread_info_flags)) {
-		fill_thread_info(tc->thread_info);
-		ti_flags = UINT(tt->thread_info + OFFSET(thread_info_flags));
-		sigpending = ti_flags & (1<<TIF_SIGPENDING);
-	}
 	
 
 	if (VALID_MEMBER(task_struct_sig))
@@ -6093,8 +6105,6 @@
 		signal_struct = ULONG(tt->task_struct + 
 			OFFSET(task_struct_signal));
 
-	fprintf(fp, "SIGNAL_STRUCT: %lx  ", signal_struct);
-
 	size = MAX(SIZE(signal_struct), VALID_SIZE(signal_queue) ?  
 		SIZE(signal_queue) : SIZE(sigqueue));
 	if (VALID_SIZE(sighand_struct))
@@ -6104,9 +6114,19 @@
 	readmem(signal_struct, KVADDR, signal_buf,
 		SIZE(signal_struct), "signal_struct buffer",
 		FAULT_ON_ERROR);
+
+	/*
+	 *  Signal dispositions (task group level).
+	 */
+	if(task_flags & TASK_GROUP_LEVEL) {
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
+		fprintf(fp, "SIGNAL_STRUCT: %lx  ", signal_struct);
 	fprintf(fp, "COUNT: %d\n",
 		INT(signal_buf + OFFSET(signal_struct_count)));
 
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	fprintf(fp, " SIG %s %s %s %s\n",
 		mkstring(buf1, VADDR_PRLEN == 8 ? 9 : VADDR_PRLEN, 
 			CENTER, "SIGACTION"),
@@ -6127,6 +6147,8 @@
 	sigrtmax = sigrt_minmax(NULL, NULL);
 
         for (i = 1; i <= sigrtmax; i++) {
+			if (task_flags & TASK_INDENT2)
+				INDENT(2);
                 fprintf(fp, "%s[%d] ", i < 10 ? " " : "", i);
 
 		if (use_sighand) {
@@ -6213,11 +6235,43 @@
 
                 fprintf(fp, "\n");
         }
+	}
+	
+	if(task_flags & TASK_LEVEL) {
+		/*
+	 	* Pending signals (task level).
+		*/
+		if (VALID_MEMBER(task_struct_sigpending))
+			sigpending = INT(tt->task_struct + 
+				OFFSET(task_struct_sigpending));
+		else if (VALID_MEMBER(thread_info_flags)) {
+			fill_thread_info(tc->thread_info);
+			ti_flags = UINT(tt->thread_info + OFFSET(thread_info_flags));
+			sigpending = ti_flags & (1<<TIF_SIGPENDING);
+		}
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	fprintf(fp, "SIGPENDING: %s\n", sigpending ? "yes" : "no");
+
+		/*
+	 	*  Blocked signals (task level).
+	 	*/
+
+		blocked = task_blocked(tc->task);
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	fprintf(fp, "   BLOCKED: %016llx\n", blocked);
 		
+		/*
+	 	*  Pending queue (task level).
+	 	*/
+	
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	if (VALID_MEMBER(signal_struct_shared_pending) )
 		fprintf(fp, "PRIVATE_PENDING\n");
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	fprintf(fp, "    SIGNAL: %016llx\n", sigset);
 
 	if (VALID_MEMBER(task_struct_sigqueue)) 
@@ -6232,13 +6286,20 @@
 	if (VALID_MEMBER(sigqueue_list) && empty_list(sigqueue))
 		sigqueue = 0;
 
+		if (task_flags & TASK_INDENT2)
+			INDENT(2);
 	if (sigqueue) {
                 fprintf(fp, "  SIGQUEUE:  SIG  %s\n",
                         mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "SIGINFO"));
 		 sigqueue_list(sigqueue);
 	} else
                 fprintf(fp, "  SIGQUEUE: (empty)\n");
+	}
 
+	/*
+	 *  Pending queue (task group level).
+	 */
+	if (task_flags & TASK_GROUP_LEVEL) {
 	if (VALID_MEMBER(signal_struct_shared_pending) ) {
 		ulong shared_pending, signal;
 		fprintf(fp, "SHARED_PENDING\n");
@@ -6247,6 +6308,8 @@
 		readmem(signal, KVADDR, signal_buf,SIZE(sigpending_signal),
 			"signal", FAULT_ON_ERROR);
 		sigset = task_signal(0, (ulong*)signal_buf);
+			if (task_flags & TASK_INDENT2)
+				INDENT(2);
 		fprintf(fp, "    SIGNAL: %016llx\n", sigset);
                 sigqueue = (shared_pending + 
 			OFFSET_OPTION(sigpending_head, sigpending_list) + 
@@ -6257,6 +6320,8 @@
 
 		if (VALID_MEMBER(sigqueue_list) && empty_list(sigqueue))
 			sigqueue = 0;
+			if (task_flags & TASK_INDENT2)
+				INDENT(2);
 		if (sigqueue) {
                		fprintf(fp, "  SIGQUEUE:  SIG  %s\n",
                        		mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "SIGINFO"));
@@ -6264,6 +6329,7 @@
 		} else
                		fprintf(fp, "  SIGQUEUE: (empty)\n");
 	}
+	}
 	FREEBUF(signal_buf);
 }
 
