Hello Dave, I have realized the function to display anonymous members of struct/union. There are three changes, which are listed below, and I will take "struct page" for example. 1. anonymous members will be showed when using "struct page" 2. anonymous member, "struct page.private", will be showed together with its offset 3. anonymous member with the address of the structure, "struct page.private xxx", will be showed. About the implementation, gdb code is changed, which is used to change the output of the gdb command, "ptype ...". And function "arg_to_datatype" is also modified to analyze anonymous member. Please refer to the patch to get more info about implementation. -- -- Regards Qiao Nuohan
diff --git a/gdb-7.3.1.patch b/gdb-7.3.1.patch index 030425c..6f2dd50 100644 --- a/gdb-7.3.1.patch +++ b/gdb-7.3.1.patch @@ -1345,3 +1345,15 @@ for (i = 0; i < lm->mod_sections; i++) { secname = lm->mod_section_data[i].name; if ((lm->mod_section_data[i].flags & SEC_FOUND) && +--- gdb-7.3.1/gdb/c-typeprint.c.orig ++++ gdb-7.3.1/gdb/c-typeprint.c +@@ -956,7 +956,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, + fprintf_filtered (stream, "static "); + c_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), +- stream, show - 1, level + 4); ++ stream, strlen(TYPE_FIELD_NAME (type, i))? ++ show - 1 : show, level + 4); + if (!field_is_static (&TYPE_FIELD (type, i)) + && TYPE_FIELD_PACKED (type, i)) + { diff --git a/symbols.c b/symbols.c index f88c016..1047737 100755 --- a/symbols.c +++ b/symbols.c @@ -111,6 +111,7 @@ static int show_member_offset(FILE *, struct datatype_member *, char *); #define IN_UNION (0x20000) #define IN_STRUCT (0x40000) #define DATATYPE_QUERY (0x80000) +#define ANON_MEMBER_QUERY (0x100000) #define INTEGER_TYPE (UINT8|INT8|UINT16|INT16|UINT32|INT32|UINT64|INT64) @@ -5087,18 +5088,30 @@ anon_member_offset(char *name, char *member) char buf[BUFSIZE]; char *arglist[MAXARGS]; ulong value; + int type; value = -1; - sprintf(buf, "print &((struct %s *)0x0)->%s", name, member); - open_tmpfile(); - if (gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { - rewind(pc->tmpfile); - if (fgets(buf, BUFSIZE, pc->tmpfile) && - (c = parse_line(strip_linefeeds(buf), arglist))) - value = stol(arglist[c-1], RETURN_ON_ERROR|QUIET, NULL); + open_tmpfile2(); + + type = 0; + while (type < 2 && value == -1) { + if (type == 0) + sprintf(buf, "print &((struct %s *)0x0)->%s", name, member); + else + sprintf(buf, "print &((union %s *)0x0)->%s", name, member); + + if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) { + rewind(pc->tmpfile2); + if (fgets(buf, BUFSIZE, pc->tmpfile2) && + (c = parse_line(strip_linefeeds(buf), arglist))) + value = stol(arglist[c-1], RETURN_ON_ERROR|QUIET, NULL); + } + + type++; + rewind(pc->tmpfile2); } - close_tmpfile(); + close_tmpfile2(); return value; } @@ -5767,7 +5780,8 @@ cmd_datatype_common(ulong flags) } else structname = args[optind]; - if ((arg_to_datatype(structname, dm, DATATYPE_QUERY|RETURN_ON_ERROR) < 1)) + if ((arg_to_datatype(structname, dm, + DATATYPE_QUERY|ANON_MEMBER_QUERY|RETURN_ON_ERROR) < 1)) error(FATAL, "invalid data structure reference: %s\n", structname); if ((argc_members > 1) && !aflag) { @@ -5800,7 +5814,8 @@ cmd_datatype_common(ulong flags) strcpy(separator+1, memberlist[i]); } - switch (arg_to_datatype(structname, dm, RETURN_ON_ERROR)) + switch (arg_to_datatype(structname, dm, + ANON_MEMBER_QUERY|RETURN_ON_ERROR)) { case 0: error(FATAL, "invalid data structure reference: %s\n", structname); @@ -5996,7 +6011,9 @@ arg_to_datatype(char *s, struct datatype_member *dm, ulong flags) dm->member = p1+1; if ((dm->member_offset = MEMBER_OFFSET(dm->name, dm->member)) < 0) - goto datatype_member_fatal; + if (!((flags & ANON_MEMBER_QUERY) && (dm->member_offset = + ANON_MEMBER_OFFSET(dm->name, dm->member)) >= 0)) + goto datatype_member_fatal; return 2; @@ -6771,7 +6788,7 @@ parse_for_member(struct datatype_member *dm, ulong flag) sprintf(lookfor2, " %s[", s); next_item: while (fgets(buf, BUFSIZE, pc->tmpfile)) { - if (STRNEQ(buf, lookfor1) || STRNEQ(buf, lookfor2)) { + if (strstr(buf, lookfor1) || strstr(buf, lookfor2)) { on++; if (strstr(buf, "= {")) indent = count_leading_spaces(buf); @@ -6882,11 +6899,6 @@ show_member_offset(FILE *ofp, struct datatype_member *dm, char *inbuf) return FALSE; } - - if (STRNEQ(inbuf, " ")) { - end_of_block = FALSE; - goto do_empty_offset; - } if (STRNEQ(inbuf, " union {")) dm->flags |= IN_UNION; if (STRNEQ(inbuf, " struct {")) @@ -6949,6 +6961,9 @@ show_member_offset(FILE *ofp, struct datatype_member *dm, char *inbuf) offset = MEMBER_OFFSET(dm->name, target); if (offset == -1) + offset = ANON_MEMBER_OFFSET(dm->name, target); + + if (offset == -1) goto do_empty_offset; if (end_of_block && dm->member) {
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility