[PATCH] displaying anonymous members of struct/union

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux