--- crash-4.0-3.7/symbols.c	2006-10-12 22:27:27.000000000 +0200
+++ crash-4.0-3.7-patch/symbols.c	2006-10-18 21:53:39.000000000 +0200
@@ -3959,10 +3959,14 @@
         sm = &struct_member;
 	count = 1;
 	rawdata = 0;
-	aflag = 0;
 	list_head_offset = 0;
 	flags = STRUCT_REQUEST;
 
+        int i=0, argc_members=0, optind_save;
+        char *p1, *p2;
+        char *structname, *members;
+        char *arglist[MAXARGS];
+
         while ((c = getopt(argcnt, args, "c:rvol:")) != EOF) {
                 switch(c)
 		{
@@ -4000,7 +4004,39 @@
 	if (argerrs || !args[optind])
 		cmd_usage(pc->curcmd, SYNOPSIS);
 
-	if ((arg_to_datatype(args[optind++], sm, FAULT_ON_ERROR) > 1) && 
+	if ((count_chars(args[optind], ',')+1) > MAXARGS) {
+                error(INFO,
+                        "too many arguments in comma-separated list!\n");
+                return;
+        }
+
+	p2= strstr(args[optind],".");
+	/*
+	 * Condition true only if we find "." 
+	 * and we have at least one charactere after ".".
+	 * IE : "task_struct.pid,tgid" or "task_struct.p" (error in this last case).
+	 * "task_struct" and "task_struct." (error in this last case) with else case.
+	*/
+	if(p2 && *(++p2)){ 
+        	structname = GETBUF(strlen(args[optind])+1);
+        	strcpy(structname, args[optind]);
+        	p1 = strstr(structname, ".")+1;
+        	members = GETBUF(strlen(args[optind])+1);
+        	strcpy(members, p2);
+        	replace_string(members, ",", ' ');
+        	argc_members = parse_line(members, arglist);
+		optind_save = optind;
+	} else
+		structname = args[optind];
+
+	do {
+		if(argc_members) {
+			*(p1-1)='.'; /* Because arg_to_datatype(). */
+               		*p1 = NULLCHAR;
+               		strcat(structname, arglist[i]);
+		}
+
+		if ((arg_to_datatype(structname, sm, FAULT_ON_ERROR) > 1) && 
 	    rawdata)
         	error(FATAL, "member-specific output not allowed with -r\n");
 
@@ -4009,11 +4045,21 @@
 		cmd_usage(pc->curcmd, SYNOPSIS); 
 	}
 	
-	if (!args[optind]) {
+		/*
+	 	* No address was passed.
+		*/
+		if (!args[++optind]) {
 		do_datatype_declaration(sm, flags | (sm->flags & TYPEDEF));
+			if (argc_members)
+				continue;
+			else
 		return;
 	}
 
+		/*
+	 	* Take care of address and count (array).
+		*/
+		aflag = 0;
 	while (args[optind]) {
 		if (clean_arg() && IS_A_NUMBER(args[optind])) { 
 			if (aflag) 
@@ -4040,7 +4086,6 @@
 		}
 		optind++;
 	}
-
 	if (!aflag)
 		error(FATAL, "no kernel virtual address argument entered\n");
 
@@ -4051,7 +4096,9 @@
 		addr -= len * abs(count);
 		addr += len;
 	}
-
+		/*
+	 	* Display data.
+		*/
 	for (c =  0; c < abs(count); c++, addr += len) {
 		if (rawdata) 
 			raw_data_dump(addr, len, flags & STRUCT_VERBOSE);
@@ -4067,6 +4114,12 @@
 			}
 		}
 	}
+	} while (++i < argc_members && (optind=optind_save));
+
+	if(argc_members){
+        	FREEBUF(structname);
+        	FREEBUF(members);
+	}
 }
 
 /*
@@ -5265,7 +5318,6 @@
 		if (!strstr(target, ";"))
 			target = NULL;
 	}
-
 	if (!target) 
 		goto do_empty_offset;
 
