[Crash-utility] [PATCH 1/1] tools: list: create O option for specifying head node offset

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Tue May 18 07:39:19 UTC 2021


Hi Firo,

sorry for the late reply.

-----Original Message-----
> This new O option is very useful to specify the head node
> offset for listing linked list whose head node embedded has a
> different offset to other node, e.g. dentry.d_subdirs(the head node)
> and dentry.d_child.
> 
> Signed-off-by: Firo Yang <firo.yang at suse.com>
> ---
>  defs.h  |  1 +
>  help.c  | 12 +++++++++++-
>  tools.c | 30 +++++++++++++++++++++++++++---
>  3 files changed, 39 insertions(+), 4 deletions(-)
> 
> diff --git a/defs.h b/defs.h
> index 35b983a..764facf 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2605,6 +2605,7 @@ struct list_data {             /* generic structure used by do_list() to walk */
>  #define LIST_PARSE_MEMBER   (VERBOSE << 13)
>  #define LIST_READ_MEMBER    (VERBOSE << 14)
>  #define LIST_BRENT_ALGO     (VERBOSE << 15)
> +#define LIST_HEAD_OFFSET_ENTERED  (VERBOSE << 16)
> 
>  struct tree_data {
>  	ulong flags;
> diff --git a/help.c b/help.c
> index 531f50a..b561f3b 100644
> --- a/help.c
> +++ b/help.c
> @@ -5716,7 +5716,7 @@ char *help__list[] = {
>  "list",
>  "linked list",
>  "[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
> -"\n       [-r|-B] [-h|-H] start",
> +"\n       [-r|-B] [-h [-O head_offset]|-H] start",
>  " ",
>  "  This command dumps the contents of a linked list.  The entries in a linked",
>  "  list are typically data structures that are tied together in one of two",
> @@ -5800,6 +5800,16 @@ char *help__list[] = {
>  "    -S struct  Similar to -s, but instead of parsing gdb output, member values",
>  "               are read directly from memory, so the command works much faster",
>  "               for 1-, 2-, 4-, and 8-byte members.",
> +"    -O offset  The -O option works only with -h option.",
> +"               It is used for specifying the offset of head node embedded in a",
> +"               structure, like dentry.d_subdirs or cgroup_subsys_state.children.",

Could I have an example usage of dentry.d_subdirs case with and without
the patch? 

I'd like to add that to the EXAMPLES section, instead of adding the
specific member names here.

Also, can it detect the end of list correctly with the patch?

> +"               The offset may be entered in either of two manners:",
> +"",
> +"               1. \"structure.member\" format.",
> +"               2. a number of bytes.",
> +"",
> +"               You can use it like the following:",
> +"               list -O <head node offset> -o <node offset> -h start -s <...>",
>  "    -l offset  Only used in conjunction with -s, if the start address argument",
>  "               is a pointer to an embedded list head (or any other similar list",
>  "               linkage structure whose first member points to the next linkage",
> diff --git a/tools.c b/tools.c
> index a26b101..792a567 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -3343,6 +3343,7 @@ void
>  cmd_list(void)
>  {
>  	int c;
> +	long head_member_offset; /* offset for head like denty.d_subdirs */

This warning is emitted:

cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6  tools.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security 
tools.c: In function ‘cmd_list’:
tools.c:3400:37: warning: ‘head_member_offset’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                                error(FATAL,
                                     ^

Thanks,
Kazu

>  	struct list_data list_data, *ld;
>  	struct datatype_member struct_member, *sm;
>  	struct syment *sp;
> @@ -3353,7 +3354,7 @@ cmd_list(void)
>  	BZERO(ld, sizeof(struct list_data));
>  	struct_list_offset = 0;
> 
> -	while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
> +	while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
>                  switch(c)
>  		{
>  		case 'B':
> @@ -3394,6 +3395,24 @@ cmd_list(void)
>  					optarg);
>  			break;
> 
> +		case 'O':
> +			if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
> +                               error(FATAL,
> +                                "offset value %d (0x%lx) already entered\n",
> +                                        head_member_offset, head_member_offset);
> +			else if (IS_A_NUMBER(optarg))
> +				head_member_offset = stol(optarg,
> +					FAULT_ON_ERROR, NULL);
> +			else if (arg_to_datatype(optarg,
> +				sm, RETURN_ON_ERROR) > 1)
> +				head_member_offset = sm->member_offset;
> +			else
> +				error(FATAL, "invalid -O argument: %s\n",
> +					optarg);
> +
> +			ld->flags |= LIST_HEAD_OFFSET_ENTERED;
> +			break;
> +
>  		case 'o':
>  			if (ld->flags & LIST_OFFSET_ENTERED)
>                                 error(FATAL,
> @@ -3599,8 +3618,13 @@ next_arg:
>  				fprintf(fp, "(empty)\n");
>  				return;
>  			}
> -		} else
> -			ld->start += ld->list_head_offset;
> +		} else {
> +			if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
> +				readmem(ld->start + head_member_offset, KVADDR,
> +					&ld->start, sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
> +			else
> +				ld->start += ld->list_head_offset;
> +		}
>  	}
> 
>  	ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
> --
> 2.30.2
> 
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://listman.redhat.com/mailman/listinfo/crash-utility





More information about the Crash-utility mailing list