[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