----- Original Message -----
----- Original Message -----
> Hi Folks,
>
> I have a second question related to crash. If there are multiple instances
> of a structure in the kernel which have the same name, how do I print them
> out?
>
> Mark discovered that as of 7ff9554b there is also a new 'struct log' in
> printk.c.
>
> crash> struct log
> struct log {
> u64 ts_nsec;
> u16 len;
> u16 text_len;
> u16 dict_len;
> u16 level;
> }
> SIZE: 16
>
> XFS also has a 'struct log' in fs/xfs/xfs_log_priv.h.
>
> How do we choose which will print?
>
> Thanks,
> Ben
Good question. And no good answer.
I'm guessing that when you enter "struct log" as a crash command, it finds
the base kernel's version first?
It's a gdb question actually, and it comes down to gdb's lookup_symbol()
function -- which has an optional "struct block" argument that narrows
down the scope to a particular range of text. But the crash utility does
not use the block argument when calling lookup_symbol() for a data structure
declaration. So whatever you get, you get...
There are a number of places where the "block" argument for a particular
function are determined, but they seem to presume that you're working from
a stack frame, which is not a concept when used with the crash utility,
because it's invoked internally as "gdb vmlinux". I'm guessing that
there are other paths that can be taken to find a legitimate "block" that
will hopefully select the correct structure definition, but I'm not that
familiar with the gdb code to tell you off-hand. And in any case, there's
certainly no way that I'm aware of that it could be done without adding
new functionality to the crash utility and its interface with the embedded
gdb module.
Interesting that nobody's ever brought this up before. There must be
other examples.
Dave
Hi Ben,
I did a cursory investigation into this issue, using a recent Fedora
3.5-era kernel with the xfs module loaded into the crash session.
As I mentioned, there is a lookup_symbol() function that takes an optional
block argument, which is essentially a data structure that is created
for the hundreds/thousands (?) of chunks of kernel text. (i.e., each block
structure has a startaddr and endaddr member). And for the purposes of
the crash utility, that field is not used (NULL is passed).
But I hacked up a function to call lookup_symbol() passing the block
structure that gets returned by the block_for_pc() function for a given
text address. And as expected, for any base kernel text address, it
will return the same pointer to the kernel's new "struct log" symbol type.
Then I loaded the "xfs" module's debuginfo into the crash session,
and passed my hack function a set of various text addresses from the
xfs module itself, thinking that reducing the scope to the xfs module's
text would cause it to pick up the xfs "log" structure. And for a few
of the xfs text addresses it did just that -- but unfortunately, for most
of them, it still ended up picking up the base kernel's "log" structure.
Perhaps some functions in the xfs module don't know about its own "struct
log"?
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...
Luckily for your example, the xfs "struct log" has a typedef that you
can use to avoid the collision:
crash> struct log
struct log {
u64 ts_nsec;
u16 len;
u16 text_len;
u16 dict_len;
u16 level;
}
SIZE: 16
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> xlog_t
typedef 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;
struct xlog_grant_head l_reserve_head;
struct xlog_grant_head l_write_head;
} xlog_t;
SIZE: 448
crash>
Dave