[Crash-utility] [Patch 0/2] Request data structures of particular size. Crash changes.

Alexandr Terekhov Alexandr_Terekhov at epam.com
Tue Apr 5 12:07:26 UTC 2016


--- crash-7.1.4/defs.h	2015-12-16 18:59:36.000000000 +0300
+++ crash-7.1.4.test/defs.h	2016-04-04 09:46:42.615294482 +0300
@@ -4340,6 +4340,7 @@
 void cmd_pointer(void);      /* symbols.c */
 void cmd_whatis(void);       /* symbols.c */
 void cmd_p(void);            /* symbols.c */
+void cmd_types(void);        /* symbols.c */
 void cmd_mount(void);        /* filesys.c */
 void cmd_files(void);        /* filesys.c */
 void cmd_fuser(void);        /* filesys.c */
@@ -4874,6 +4875,7 @@
 extern char *help_sys[];
 extern char *help_task[];
 extern char *help_timer[];
+extern char *help_types[];
 extern char *help_union[];
 extern char *help_vm[];
 extern char *help_vtop[];
@@ -6235,7 +6237,7 @@
  *  gdb/symtab.c
  */
 extern void gdb_command_funnel(struct gnu_request *);
-
+extern int search_matched_struct_symbols (const char *, int, int, const char ***, int **);
 /*
  *  gdb/symfile.c
  */
--- crash-7.1.4/global_data.c	2015-12-16 18:59:36.000000000 +0300
+++ crash-7.1.4.test/global_data.c	2016-03-31 16:35:25.753285231 +0300
@@ -114,6 +114,7 @@
         {"task",    cmd_task,    help_task,    REFRESH_TASK_TABLE},
 	{"test",    cmd_test,    NULL,         HIDDEN_COMMAND},
         {"timer",   cmd_timer,   help_timer,   0},
+	{"types",   cmd_types,   help_types,   0},
 	{"union",   cmd_union,   help_union,   0},
 	{"vm",      cmd_vm,      help_vm,      REFRESH_TASK_TABLE},
 	{"vtop",    cmd_vtop,    help_vtop,    REFRESH_TASK_TABLE},
--- crash-7.1.4/help.c	2015-12-16 18:59:36.000000000 +0300
+++ crash-7.1.4.test/help.c	2016-04-01 13:08:48.878755448 +0300
@@ -5658,6 +5658,62 @@
 NULL
 };
 
+char *help_types[] = {
+"types",
+"search declared structures with particular size and contents",
+"[-f field] -r range",
+"The arguments are as follows:\n",
+"   -f field    The field type (or substruct of type name) which the",
+"               structure should contain",
+"   -r range    The range or the exact size of the structure we're",
+"               looking for.",
+"\nEXAMPLES:",
+"\n1. Find all structures which have size from 190 up to 200 bytes\n\n"
+"   %s> types -r 190-200",
+"192	apic",
+"192	ata_eh_context",
+"192	cper_sec_proc_generic",
+"192	cpuinfo_x86",
+"192	pebs_record_hsw",
+"196	ethtool_drvinfo",
+"196	kioctx",
+"196	vm86plus_struct",
+"200	apple_sc",
+"200	cper_pstore_record",
+"200	kernel_vm86_struct",
+"200	linux_binprm",
+"200	scsi_transport_template",
+"\n2. Find all structures which have size from 190 up to 200 bytes and",
+"which contain member of type '*list*'\n",
+"   %s> types -r 190-200 -f list",
+"196	kioctx",
+"200	scsi_transport_template",
+"",
+"`struct kioctx` really has members of types `hlist_node`, `list_head`.",
+"However, the last structure is more subtle. It contains field of type",
+"`list_head` within itself.",
+"That is:",
+"`scsi_transport_template` contains member of type `transport_container`",
+"`transport_container` has `attribute_container`", 
+"`attribute_container` has `list_head`.",
+"Structure `list_head` has poiners to `list_head`",
+"This is the place where algorithm triggers. It delves into the structure",
+"_only_ if the particular member is a structure, not a pointer.",
+"If it is a pointer, we only match name of type against the given pattern.",
+"\n3. Find all ths structures which have size exactly 36 bytes and which",
+"contain member of type '*list_head*'\n",
+"   %s> types -r 36 -f list_head",
+"36	agp_front_data",
+"36	audit_watch",
+"36	blkio_cgroup",
+"36	blkio_policy_type",
+"36	device_domain_info",
+"36	dmar_drhd_unit",
+"36	dmar_rmrr_unit",
+"........",
+NULL
+};
+
 char *help_ptob[] = {
 "ptob",
 "page to bytes",
--- crash-7.1.4/symbols.c	2015-12-16 18:59:36.000000000 +0300
+++ crash-7.1.4.test/symbols.c	2016-04-04 10:12:40.271317840 +0300
@@ -33,6 +33,7 @@
 static int compare_syms(const void *, const void *);
 static int compare_mods(const void *, const void *);
 static int compare_prios(const void *v1, const void *v2);
+static int compare_size_name(const void *, const void *);
 static asection *get_kernel_section(char *);
 static char * get_section(ulong vaddr, char *buf);
 static void symbol_dump(ulong, char *);
@@ -5976,6 +5977,74 @@
 	return TRUE;
 }
 
+static int
+compare_size_name(const void *va, const void *vb) {
+	const struct {
+		char *n; int s;
+	} *a = va, *b = vb;
+
+	if (a->s == b->s)
+		return strcmp(a->n, b->n);
+	else
+		return a->s < b->s ? -1 : 1;
+}
+
+void
+cmd_types(void)
+{
+	const char *field = NULL, **out_name = NULL;
+	char *sep, tmp[16];
+
+	int lowest, highest, i, c;
+	int *out_size = NULL;
+	struct { const char *n; int s; } *struct_output;
+
+	lowest = highest = UNUSED;
+
+	while ((c = getopt(argcnt, args, "f:r:")) != EOF) {
+		switch (c)
+		{
+		case 'f':
+			field = optarg;
+			break;
+		case 'r':
+			strncpy(tmp, optarg, 15);
+			if ((sep = strstr(tmp, "-")) != NULL)
+				*(sep++) = '\0';
+
+			lowest = stol(tmp, FAULT_ON_ERROR, NULL);
+
+			if (sep)
+				highest = stol(sep, FAULT_ON_ERROR, NULL);
+			else
+				highest = lowest;
+
+			break;
+		default:
+			cmd_usage(pc->curcmd, SYNOPSIS);
+		}
+	}
+
+	if (lowest == UNUSED || highest == UNUSED)
+		error(FATAL, "You should specify range\n");
+
+	c = search_matched_struct_symbols(field, lowest, highest,
+		&out_name, &out_size);
+
+	struct_output = malloc(sizeof(*struct_output) * c);
+	for (i = 0; i < c; i++) {
+		struct_output[i].n = out_name[i];
+		struct_output[i].s = out_size[i];
+	}
+
+	qsort(struct_output, c, sizeof(*struct_output), compare_size_name);
+
+	for (i = 0; i < c; i++)
+		fprintf(fp, "%d\t%s\n", struct_output[i].s, struct_output[i].n);
+
+	free(struct_output);
+	return;	
+}
 static void 
 cmd_datatype_common(ulong flags)
 {




More information about the Crash-utility mailing list