[Crash-utility] enhance print command

Dave Anderson anderson at redhat.com
Fri Feb 1 14:11:34 UTC 2008


Ming Zhang wrote:
> Hi All
> 
> I wonder if this is doable or already there? Now for example, if use
> "print" to check a function pointer array, it only shows the content.
> then for each value, we have run sym <value> to see which symbol it is.
> is it possible for the "print" command do this automatically? Thanks.
> 
> 
> 

It's all handled by the embedded gdb module, and it does attempt
to translate structure members that are declared as function pointers.

Take the file_operations structure for exmample:

crash> file_operations
struct file_operations {
     struct module *owner;
     loff_t (*llseek)(struct file *, loff_t, int);
     ssize_t (*read)(struct file *, char *, size_t, loff_t *);
     ssize_t (*aio_read)(struct kiocb *, char *, size_t, loff_t);
     ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
     ssize_t (*aio_write)(struct kiocb *, const char *, size_t, loff_t);
     int (*readdir)(struct file *, void *, filldir_t);
     unsigned int (*poll)(struct file *, struct poll_table_struct *);
     int (*ioctl)(struct inode *, struct file *, unsigned int, long unsigned int);
     long int (*unlocked_ioctl)(struct file *, unsigned int, long unsigned int);
     long int (*compat_ioctl)(struct file *, unsigned int, long unsigned int);
     int (*mmap)(struct file *, struct vm_area_struct *);
     int (*open)(struct inode *, struct file *);
     int (*flush)(struct file *, fl_owner_t);
     int (*release)(struct inode *, struct file *);
     int (*fsync)(struct file *, struct dentry *, int);
     int (*aio_fsync)(struct kiocb *, int);
     int (*fasync)(int, struct file *, int);
     int (*lock)(struct file *, int, struct file_lock *);
     ssize_t (*readv)(struct file *, const struct iovec *, long unsigned int, 
loff_t *);
     ssize_t (*writev)(struct file *, const struct iovec *, long unsigned int, 
loff_t *);
     ssize_t (*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void *);
     ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);
     long unsigned int (*get_unmapped_area)(struct file *, long unsigned int, 
long unsigned int, long unsigned int
, long unsigned int);
     int (*check_flags)(int);
     int (*dir_notify)(struct file *, long unsigned int);
     int (*flock)(struct file *, int, struct file_lock *);
     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, 
size_t, unsigned int);
     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, 
size_t, unsigned int);
}
SIZE: 116
crash>

And then here's an instance of one:

crash> whatis sysfs_file_operations
const struct file_operations sysfs_file_operations;
crash> p sysfs_file_operations
sysfs_file_operations = $5 = {
   owner = 0x0,
   llseek = 0xc04704d5 <generic_file_llseek>,
   read = 0xc04a4fb7 <sysfs_read_file>,
   aio_read = 0,
   write = 0xc04a49ab <sysfs_write_file>,
   aio_write = 0,
   readdir = 0,
   poll = 0xc04a4966 <sysfs_poll>,
   ioctl = 0,
   unlocked_ioctl = 0,
   compat_ioctl = 0,
   mmap = 0,
   open = 0xc04a4c92 <sysfs_open_file>,
   flush = 0,
   release = 0xc04a4e31 <sysfs_release>,
   fsync = 0,
   aio_fsync = 0,
   fasync = 0,
   lock = 0,
   readv = 0,
   writev = 0,
   sendfile = 0,
   sendpage = 0,
   get_unmapped_area = 0,
   check_flags = 0,
   dir_notify = 0,
   flock = 0,
   splice_write = 0,
   splice_read = 0
}
crash>

If it's from a module, it will require its debuginfo to be loaded:

crash> p ext3_file_operations
p: gdb request failed: p ext3_file_operations
crash> mod -s ext3
  MODULE   NAME                  SIZE  OBJECT FILE
e08c4f80  ext3                123337 
/lib/modules/2.6.18-53.el5/kernel/fs/ext3/ext3.ko
crash> p ext3_file_operations
ext3_file_operations = $8 = {
   owner = 0x0,
   llseek = 0xc04704d5 <generic_file_llseek>,
   read = 0xc046f9d6 <do_sync_read>,
   aio_read = 0xc0455989 <generic_file_aio_read>,
   write = 0xc046f8e5 <do_sync_write>,
   aio_write = 0xe08a9e70 <ext3_file_write>,
   readdir = 0,
   poll = 0,
   ioctl = 0xe08ae388 <ext3_ioctl>,
   unlocked_ioctl = 0,
   compat_ioctl = 0,
   mmap = 0xc0454476 <generic_file_mmap>,
   open = 0xc046e4a6 <generic_file_open>,
   flush = 0,
   release = 0xe08a9ef3 <ext3_release_file>,
   fsync = 0xe08a9f50 <ext3_sync_file>,
   aio_fsync = 0,
   fasync = 0,
   lock = 0,
   readv = 0xc0456b24 <generic_file_readv>,
   writev = 0xc045662a <generic_file_writev>,
   sendfile = 0xc0455109 <generic_file_sendfile>,
   sendpage = 0,
   get_unmapped_area = 0,
   check_flags = 0,
   dir_notify = 0,
   flock = 0,
   splice_write = 0xc0490781 <generic_file_splice_write>,
   splice_read = 0xc0490809 <generic_file_splice_read>
}
crash>

If the debuginfo data is not available, or for whatever reason
you're not getting symbolic translations, you can always "rd -s"
the memory symbolically, which is probably more efficient than
running "sym" on each address.

For example, the file_operations structure is 116 bytes long, or
29 words on an 32-bit system.  Even if I didn't have the ext3 module's
debuginfo available, crash still knows about its exported symbols:

crash> rd -s ext3_file_operations 29
e08b8d40:  00000000 generic_file_llseek do_sync_read generic_file_aio_read
e08b8d50:  do_sync_write ext3_file_write 00000000 00000000
e08b8d60:  ext3_ioctl 00000000 00000000 generic_file_mmap
e08b8d70:  generic_file_open 00000000 ext3_release_file ext3_sync_file
e08b8d80:  00000000 00000000 00000000 generic_file_readv
e08b8d90:  generic_file_writev generic_file_sendfile 00000000 00000000
e08b8da0:  00000000 00000000 00000000 generic_file_splice_write
e08b8db0:  generic_file_splice_read
crash>

Hope this helps,
   Dave














More information about the Crash-utility mailing list