[Crash-utility] multiple structs with the same name

Dave Anderson anderson at redhat.com
Thu Jun 14 19:45:55 UTC 2012



----- Original Message -----
>
> 
> Anyway, it would be extremely messy trying to figure out a way to:
> 
> (1) figure out the correct text address to use to find a "block" that
>     would actually work, and
> (2) somehow apply that text address to all of the crash functions that
>     display data structures, and
> (3) shoe-horn it into the current crash-gdb interface.
> 
> I suppose anything's possible, but I'm personally not going to carry
> it any farther forward.  But if someone is interested in proposing
> a scheme to do so, as always, I'll listen...

I can't help myself -- maybe it wouldn't be so hard to implemente if I take
a sledgehammer approach...

For example, I created a global "crash_block" pointer in the crash sources
like this:

  struct block *crash_block;
  extern struct block *block_for_pc(ulong);
 
And then hacked up the built-in-but-hidden "test" command to
accept a text address, call block_for_pc() to get its block address,
and assign it to the global crash_block above.

Then in the gdb code, I put this in place, where lookup_symbol()
currently always receives a NULL block pointer:

  struct symbol *
  lookup_symbol (const char *name, const struct block *block,
                 domain_enum domain, int *is_a_field_of_this)
  {
+   if (!block) {
+           extern struct block *crash_block;
+           block = crash_block;
+   }
    return lookup_symbol_in_language (name, block, domain,
                                      current_language->la_language,
                                      is_a_field_of_this);
  }
  
So without setting the crash_block, you get the normal behavior:
  
  crash> struct log
  struct log {
      u64 ts_nsec;
      u16 len;
      u16 text_len;
      u16 dict_len;
      u16 level;
  }
  SIZE: 16
  crash>

Then I load the xfs module debuginfo, and dump its symbols:

  crash> mod -s xfs
       MODULE       NAME                       SIZE  OBJECT FILE
  ffffffffa02d67c0  xfs                      816241  /lib/modules/3.5.0-0.rc1.git0.1.fc18.x86_64/kernel/fs/xfs/xfs.ko 
  crash> sym -m xfs
  ffffffffa0239000 MODULE START: xfs
  14700 (D) xfsstats
  ffffffffa0239000 (t) ftrace_raw_output_xfs_discard_class
  ffffffffa02390e0 (t) ftrace_raw_output_xfs_log_recover_ino_item_class
  ffffffffa02391f0 (t) ftrace_raw_output_xfs_log_recover_buf_item_class
  ffffffffa02392e0 (t) ftrace_raw_output_xfs_free_extent
  ffffffffa0239410 (t) ftrace_raw_output_xfs_trans_commit_lsn
  ffffffffa02394f0 (t) ftrace_raw_output_xfs_extent_busy_trim
  ffffffffa02395e0 (t) ftrace_raw_output_xfs_extent_busy_class
  ffffffffa02396c0 (t) ftrace_raw_output_xfs_pagecache_inval
  ffffffffa02397b0 (t) ftrace_raw_output_xfs_itrunc_class
  ffffffffa0239890 (t) ftrace_raw_output_xfs_simple_io_class
  ffffffffa0239990 (t) ftrace_raw_output_xfs_page_class
  ffffffffa0239a90 (t) ftrace_raw_output_xfs_log_force
  ffffffffa0239b60 (t) ftrace_raw_output_xfs_rename
  ... [cut] ...

Picking out the address of "ftrace_raw_output_xfs_rename" (because it's
it's one of the xfs addresses that sees its own "struct log"), I get its
block address, and set the global "crash_block" to 6495890:

  crash> test ffffffffa02397b0
  block_for_pc(ffffffffa02397b0): 6495890
  crash>

And lo and behold:

  crash> struct log
  struct log {
      struct xfs_mount *l_mp;
      struct xfs_ail *l_ailp;
      struct xfs_cil *l_cilp;
      struct xfs_buf *l_xbuf;
      struct xfs_buftarg *l_targ;
      uint l_flags;
      uint l_quotaoffs_flag;
      struct list_head *l_buf_cancel_table;
      int l_iclog_hsize;
      int l_iclog_heads;
      uint l_sectBBsize;
      int l_iclog_size;
      int l_iclog_size_log;
      int l_iclog_bufs;
      xfs_daddr_t l_logBBstart;
      int l_logsize;
      int l_logBBsize;
      wait_queue_head_t l_flush_wait;
      int l_covered_state;
      xlog_in_core_t *l_iclog;
      spinlock_t l_icloglock;
      int l_curr_cycle;
      int l_prev_cycle;
      int l_curr_block;
      int l_prev_block;
      atomic64_t l_last_sync_lsn;
      atomic64_t l_tail_lsn;
  crash>

To set it back to base kernel, I can either clear the "crash_block",
or for example, set it to sys_read()'s block, and I get the base
kernel's view:

  crash> sym sys_read
  ffffffff81185000 (T) sys_read ../debug/k3.nel-3.4.fc18/linux-3.5.0-0.rc1.git0.1.fc18.x86_64/fs/read_write.c: 461
  crash> test ffffffff81185000
  block_for_pc(ffffffff81185000): 69648f0
  crash> struct log
  struct log {
      u64 ts_nsec;
      u16 len;
      u16 text_len;
      u16 dict_len;
      u16 level;
  }
  SIZE: 16
  crash> 

So I suppose we *could* have a new crash "block" environment variable,
settable with the "set" command, and then while it's in play you would
see stuff based upon that particular scope.  Hmmm...

I just wonder if it's worth it given the parcity of actual examples of
multiple structs with the same name.  That's why I'm wondering if anybody
else on the list has run into this kind of problem?

Dave





More information about the Crash-utility mailing list