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