FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Crash Utility

 
 
LinkBack Thread Tools
 
Old 03-05-2012, 07:20 AM
qiaonuohan
 
Default 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
 

Thread Tools




All times are GMT. The time now is 06:01 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org