Modified. I remain the "-N" option. But for radix tree on RHEL5 or
below, the height does not exist. So "-N" is not supported for radix
tree on these version.
At 2012-5-30 3:56, Dave Anderson wrote:
----- Original Message -----
>
>
> ----- Original Message -----
> As it turns out, the radix tree problem I reported seems to be an issue
> associated with the kernel version.
> But when I try the same thing on a RHEL5 kernel, it always fails like
> this:
>
> crash> tree -t radix -r address_space.page_tree ffff81012eab2e00
> radix_tree_node at ffff81011f9932e8
> struct radix_tree_node {
> count = 0x6,
> slots = {0xffff810103c06490, 0xffff810103c1c760,
> 0xffff810103c58580, 0xffff810103bfb750, 0xffff810103e84cd8,
> 0xffff810103bf8b5
> 8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
> , 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
> tags = {{0x0}, {0x0}}
> }
> tree: height 1536 is greater than height_to_maxindex[]
> index 12
> crash>
The reason that the command fails on RHEL5 is due to this part of
your patch:
3766 void rdtree_iteration(ulong node_p, struct tree_data *td, char * ppos, ulong
indexnum)
3767 {
3768 uint height;
3769 ulong slot;
3770 int index;
3771 int i;
3772 char pos[BUFSIZE];
3773
3774 if (indexnum != -1)
3775 sprintf(pos, "%s/%ld", ppos, indexnum);
3776 else
3777 sprintf(pos, "%s", ppos);
3778
3779 readmem(node_p + MEMBER_OFFSET("radix_tree_node",
"height"), KVADDR,
3780&height, sizeof(uint), "radix_tree_node height", FAULT_ON_ERROR);
3781
3782 if (height> ARRAY_LENGTH(height_to_maxindex)) {
3783 fprintf(fp, "radix_tree_node at %lx\n", node_p);
3784 dump_struct("radix_tree_node", node_p, RADIX(16));
3785 error(FATAL, "height %d is greater than
height_to_maxindex[] \
3786 index %ld\n", height,
ARRAY_LENGTH(height_to_maxindex));
3787 }
In line 3779, you calculate "height" using:
MEMBER_OFFSET("radix_tree_node", "height")
which returns -1, because RHEL5's radix_tree_node does not have a "height"
member:
crash> radix_tree_node
struct radix_tree_node {
unsigned int count;
void *slots[64];
long unsigned int tags[2][1];
}
SIZE: 536
crash>
In RHEL6, a radix_tree_node structure does have a "height" member:
crash> radix_tree_node
struct radix_tree_node {
unsigned int height;
unsigned int count;
struct rcu_head rcu_head;
void *slots[64];
long unsigned int tags[3][1];
}
SIZE: 560
crash>
In any case, I now see that your patch uses MEMBER_OFFSET(...) in 4 places:
$ grep MEMBER_OFFSET 0001-add-a-new-command-tree.patch
+ readmem(node_p + MEMBER_OFFSET("radix_tree_node", "height"),
KVADDR,
+ readmem(td->start + MEMBER_OFFSET("rb_root",
"rb_node"), KVADDR,
+ readmem(node_p+MEMBER_OFFSET("rb_node", "rb_left"),
KVADDR,&left_p,
+ readmem(node_p+MEMBER_OFFSET("rb_node", "rb_right"),
KVADDR,&right_p,
$
which is not acceptable, because it hides these kinds of programming errors.
For each of the 4 structure members above, add them to the offset_table[] array,
initialize them with MEMBER_OFFSET_INIT(), and use OFFSET(...) instead of
MEMBER_OFFSET(). Then if your code is incorrect as above, it will fail
immediately and show a meaningful error message.
Dave
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility