Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Crash Utility (http://www.linux-archive.org/crash-utility/)
-   -   displaying anonymous members of struct/union (http://www.linux-archive.org/crash-utility/640855-displaying-anonymous-members-struct-union.html)

qiaonuohan 03-05-2012 07:20 AM

displaying anonymous members of struct/union
 
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
", 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
",
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@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility


All times are GMT. The time now is 05:17 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.