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(a)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(a)redhat.com
https://listman.redhat.com/mailman/listinfo/crash-utility