[Crash-utility] [PATCH] foreach filter on state
Dave Anderson
anderson at redhat.com
Thu Mar 8 15:53:02 UTC 2012
----- Original Message -----
> 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
I like this idea. But for the sake of conformity, I will change the
state identifiers to be the same two-letter strings that the "ps"
command uses. Queued for crash-6.0.5.
Thanks,
Dave
>
> 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)
> --
More information about the Crash-utility
mailing list