The patch below adds support to filter foreach on task states. I've found [foreach state=D bt] and [foreach state=R bt] useful; the former allows to emulate the show-blocked-tasks Magic SysRq. Rabin diff --git a/defs.h b/defs.h index 2e7f6bd..dc12844 100755 --- a/defs.h +++ b/defs.h @@ -974,6 +974,7 @@ extern struct machdep_table *machdep; #define FOREACH_F_FLAG (0x400000) #define FOREACH_x_FLAG (0x800000) #define FOREACH_d_FLAG (0x1000000) +#define FOREACH_STATE (0x2000000) struct foreach_data { ulong flags; @@ -982,6 +983,7 @@ struct foreach_data { char *comm_array[MAX_FOREACH_COMMS]; ulong pid_array[MAX_FOREACH_PIDS]; ulong arg_array[MAX_FOREACH_ARGS]; + ulong state; char *reference; int keys; int pids; diff --git a/help.c b/help.c index adaaea7..dedf479 100755 --- a/help.c +++ b/help.c @@ -736,7 +736,9 @@ char *help_foreach[] = { " precede the name string with a \"\\\".", " user perform the command(s) on all user (non-kernel) threads.", " kernel perform the command(s) on all kernel threads.", -" active perform the command(s) on the active thread on each CPU.\n", +" active perform the command(s) on the active thread on each CPU.", +" state=? perform the command(s) on all tasks in the specified state.", +" (? is one of R, S, D, T, Z, X, W)\n", " If none of the task-identifying arguments above are entered, the command", " will be performed on all tasks.\n", " command select one or more of the following commands to be run on the tasks", @@ -793,6 +795,9 @@ char *help_foreach[] = { " Display the open files for all tasks:\n", " %s> foreach files", " ...\n", +" Display the stack traces for all blocked (TASK_UNINTERRUPTIBLE) tasks:\n", +" %s> foreach state=D bt", +" ...\n", NULL }; diff --git a/task.c b/task.c index 433a043..de033c3 100755 --- a/task.c +++ b/task.c @@ -5061,6 +5061,35 @@ cmd_foreach(void) continue; } + if (STRNEQ(args[optind], "state=")) { + const char *p = args[optind] + strlen("state="); + ulong state = 0; + + if (STREQ(p, "R")) + state = _RUNNING_; + else if (STREQ(p, "S")) + state = _INTERRUPTIBLE_; + else if (STREQ(p, "D")) + state = _UNINTERRUPTIBLE_; + else if (STREQ(p, "T")) + state = _STOPPED_; + else if (STREQ(p, "Z")) + state = _ZOMBIE_; + else if (STREQ(p, "X")) + state = _DEAD_; + else if (STREQ(p, "W")) + state = _SWAPPING_; + else if (*p) + error(FATAL, "invalid state: %s\n", p); + else + error(FATAL, "no state specified\n"); + + fd->flags |= FOREACH_STATE; + fd->state = state; + optind++; + continue; + } + /* * Select only user threads. */ @@ -5322,6 +5351,9 @@ foreach(struct foreach_data *fd) if ((fd->flags & FOREACH_KERNEL) && !is_kernel_thread(tc->task)) continue; + if ((fd->flags & FOREACH_STATE) && task_state(tc->task) != fd->state) + continue; + if (specified) { for (j = 0; j < fd->tasks; j++) if (fd->task_array[j] == tc->task) -- 1.7.9.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility