[Crash-utility] [PATCH v2 2/3] tree: add an option to dump the tree sorted

Daniel Vacek neelx at redhat.com
Mon Apr 16 17:59:51 UTC 2018


v2: limit example to 80 columns and fill -l in synopsis as well
---
 defs.h  |  1 +
 help.c  | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 tools.c | 20 ++++++++++++++++++--
 3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/defs.h b/defs.h
index adddb9f2748d..ec298cbd70be 100644
--- a/defs.h
+++ b/defs.h
@@ -2480,6 +2480,7 @@ struct tree_data {
 #define TREE_STRUCT_RADIX_16      (VERBOSE << 6)
 #define TREE_PARSE_MEMBER         (VERBOSE << 7)
 #define TREE_READ_MEMBER          (VERBOSE << 8)
+#define TREE_LINEAR_ORDER         (VERBOSE << 9)
 
 #define ALIAS_RUNTIME  (1)
 #define ALIAS_RCLOCAL  (2)
diff --git a/help.c b/help.c
index c5cec5365962..3f9a404ee3c0 100644
--- a/help.c
+++ b/help.c
@@ -5658,7 +5658,7 @@ NULL
 char *help_tree[] = {
 "tree",
 "display radix tree or red-black tree",
-"-t [radix|rbtree] [-r offset] [-[s|S] struct[.member[,member]] -[x|d]]\n          [-o offset] [-p] [-N] start",
+"-t [radix|rbtree] [-r offset] [-[s|S] struct[.member[,member]] -[x|d]]\n          [-o offset] [-p] [-l] [-N] start",
 "  This command dumps the contents of a radix tree or a red-black tree.",
 "  The arguments are as follows:\n",
 "    -t type  The type of tree to dump; the type string can be either ",
@@ -5698,6 +5699,8 @@ char *help_tree[] = {
 "             indicates \"root/l/r\" means that the node is the right child",
 "             of the left child of the root node.  For radix trees, the height",
 "             and slot index values are shown with respect to the root.",
+"         -l  Dump the tree sorted in linear order starting with the leftmost",
+"             node and progressing to the right.",
 " ",
 "  The meaning of the \"start\" argument, which can be expressed either in",
 "  hexadecimal format or symbolically, depends upon whether the -N option",
@@ -5823,6 +5826,59 @@ char *help_tree[] = {
 "    ffffea000407de58",
 "      position: root/3/28",
 "",
+"  Given the mm_struct address of 0xffff880074b5be80 list the VMA tree in linear",
+"  order from the leftmost node progressing to the right using the -l option:\n",
+"    %s> tree -ls vm_area_struct.vm_start -o vm_area_struct.vm_rb \\",
+"    -r mm_struct.mm_rb 0xffff880074b5be80 | paste - -",
+"    ffff88001f2c50e0	  vm_start = 0x400000",
+"    ffff88001f2c5290	  vm_start = 0xceb000",
+"    ffff880074bfc6c0	  vm_start = 0xcec000",
+"    ffff88001f2c4bd0	  vm_start = 0xd10000",
+"    ffff880074bfc948	  vm_start = 0x1fe9000",
+"    ffff880036e54510	  vm_start = 0x7ff6aa296000",
+"    ffff88001f2c5bd8	  vm_start = 0x7ff6aa298000",
+"    ffff880036e54af8	  vm_start = 0x7ff6aa497000",
+"    ffff880036e54f30	  vm_start = 0x7ff6aa498000",
+"    ffff88000e06aa20	  vm_start = 0x7ff6aa499000",
+"    ffff88000e06b368	  vm_start = 0x7ff6ab95f000",
+"    ...",
+"    ffff88001f2c5e60	  vm_start = 0x7ff6bc1af000",
+"    ffff88001f2c4ca8	  vm_start = 0x7ff6bc1b6000",
+"    ffff88001f2c5008	  vm_start = 0x7ff6bc200000",
+"    ffff88001f2c5d88	  vm_start = 0x7ff6bc205000",
+"    ffff880074bfd6c8	  vm_start = 0x7ff6bc206000",
+"    ffff88001f2c4288	  vm_start = 0x7ff6bc207000",
+"    ffff88001f2c4510	  vm_start = 0x7ffc7a5fc000",
+"    ffff88001f2c5b00	  vm_start = 0x7ffc7a6d1000",
+"",
+"  Compared to the top/down root/leaves order:\n",
+"    %s> tree -s vm_area_struct.vm_start -o vm_area_struct.vm_rb \\",
+"    -r mm_struct.mm_rb 0xffff880074b5be80 | paste - -",
+"    ffff88001f2c5a28	  vm_start = 0x7ff6bbbb9000",
+"    ffff88001f2c55f0	  vm_start = 0x7ff6bb252000",
+"    ffff88000e06a360	  vm_start = 0x7ff6ac6c3000",
+"    ffff88001f2c4bd0	  vm_start = 0xd10000",
+"    ffff88001f2c5290	  vm_start = 0xceb000",
+"    ffff88001f2c50e0	  vm_start = 0x400000",
+"    ffff880074bfc6c0	  vm_start = 0xcec000",
+"    ffff88000e06b368	  vm_start = 0x7ff6ab95f000",
+"    ffff88001f2c5bd8	  vm_start = 0x7ff6aa298000",
+"    ffff880074bfc948	  vm_start = 0x1fe9000",
+"    ffff880036e54510	  vm_start = 0x7ff6aa296000",
+"    ffff880036e54f30	  vm_start = 0x7ff6aa498000",
+"    ffff880036e54af8	  vm_start = 0x7ff6aa497000",
+"    ffff88000e06aa20	  vm_start = 0x7ff6aa499000",
+"    ffff88000e06ae58	  vm_start = 0x7ff6ac1df000",
+"    ffff88000e06ba28	  vm_start = 0x7ff6abefc000",
+"    ffff88000e06a6c0	  vm_start = 0x7ff6ac41b000",
+"    ffff88001f2c4000	  vm_start = 0x7ff6bac75000",
+"    ffff88000e06bd88	  vm_start = 0x7ff6b2d00000",
+"    ffff88000e06b440	  vm_start = 0x7ff6b28de000",
+"    ...",
+"    ffff880074bfd6c8	  vm_start = 0x7ff6bc206000",
+"    ffff88001f2c4510	  vm_start = 0x7ffc7a5fc000",
+"    ffff88001f2c5b00	  vm_start = 0x7ffc7a6d1000",
+"",
 "  Alternatively, take the address of the radix_tree_node from the",
 "  radix_tree_root structure in the address_space structure above,",
 "  and display the tree with the -N option:\n",
diff --git a/tools.c b/tools.c
index 7c7f65ac558b..b8e19e4284c5 100644
--- a/tools.c
+++ b/tools.c
@@ -3926,7 +3926,7 @@ cmd_tree()
 	td = &tree_data;
 	BZERO(td, sizeof(struct tree_data));
 
-	while ((c = getopt(argcnt, args, "xdt:r:o:s:S:pN")) != EOF) {
+	while ((c = getopt(argcnt, args, "xdt:r:o:s:S:plN")) != EOF) {
 		switch (c)
 		{
 		case 't':
@@ -3993,6 +3993,10 @@ cmd_tree()
 			td->flags |= TREE_POSITION_DISPLAY;
 			break;
 
+		case 'l':
+			td->flags |= TREE_LINEAR_ORDER;
+			break;
+
 		case 'N':
 			td->flags |= TREE_NODE_POINTER;
 			break;
@@ -4397,6 +4401,17 @@ rbtree_iteration(ulong node_p, struct tree_data *td, char *pos)
 	else
 		error(FATAL, "\nduplicate tree entry: %lx\n", node_p);
 
+	if (td->flags & TREE_LINEAR_ORDER &&
+		   readmem(node_p+OFFSET(rb_node_rb_left), KVADDR, &new_p,
+			sizeof(void *), "rb_node rb_left", RETURN_ON_ERROR) && new_p)
+		if (readmem(new_p+OFFSET(rb_node_rb_left), KVADDR, &test_p,
+			sizeof(void *), "rb_node rb_left", RETURN_ON_ERROR|QUIET)) {
+			sprintf(new_pos, "%s/l", pos);
+			rbtree_iteration(new_p, td, new_pos);
+		} else
+			error(INFO, "rb_node: %lx: corrupted rb_left pointer: %lx\n",
+					node_p, new_p);
+
 	struct_p = node_p - td->node_member_offset;
 
 	if (td->flags & VERBOSE)
@@ -4430,7 +4445,8 @@ rbtree_iteration(ulong node_p, struct tree_data *td, char *pos)
 		}
 	}
 
-	if (	   readmem(node_p+OFFSET(rb_node_rb_left), KVADDR, &new_p,
+	if (!(td->flags & TREE_LINEAR_ORDER) &&
+		   readmem(node_p+OFFSET(rb_node_rb_left), KVADDR, &new_p,
 			sizeof(void *), "rb_node rb_left", RETURN_ON_ERROR) && new_p)
 		if (readmem(new_p+OFFSET(rb_node_rb_left), KVADDR, &test_p,
 			sizeof(void *), "rb_node rb_left", RETURN_ON_ERROR|QUIET)) {
-- 
2.17.0




More information about the Crash-utility mailing list