[Crash-utility] Adding a new command rbtree

Dave Anderson anderson at redhat.com
Tue May 29 19:56:11 UTC 2012



----- 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

 




More information about the Crash-utility mailing list