快速定位函数指针所指向的函数原型

在一些大型开源软件中,通常会有函数指针的应用,函数指针可以让程序在运行过程中,动态的的去调用对应的回调函数。

linux内核代码中,也有大量的函数指针应用。

例子:

linux中支持大量的文件系统,如ramfs,ext3,ext4,jffs2,procfs,sysfs,nfs,debugfs,等等等,这些文件系统通过VFS虚拟文件系统统一接口,来实现调用具体文件系统的读写接口。这里就会用到函数指针来实现。比如:app在一个目录中创建文件,并向这个文件写入数据。这种情况下,不同的文件系统,会调用不同的read、write接口。因为每种文件系统的设计思想和实现方法都不一样。每种文件系统都有自己的一套读写接口。

问题:当我们debug一个程序时,通过printk等方式定位到程序走进了一个函数指针,而这个函数指针所指向的具体函数可能有好几十个。这种情况下,我们如何知道程序到底跑到哪了呢??

如果采用非常笨的方法,比如,把所有该指针可能指向的函数原型中添加打印,然后执行程序,通过打印信息看到底走了哪一个回调。显然比较慢。

方法:

我们可以通过函数的执行地址+nm工具,来快速定位函数的走向。

(1)在程序调用函数指针前,用printk打印出函数指针的地址。

(2)通过函数符号地址,在elf文件中查找该地址。nm vmlinux | grep 0x81190db0

扫描二维码关注公众号,回复: 2905972 查看本文章
/tmp # ./renameat2
[  901.270837] SYSC_renameat2 4500
[  901.272295] SYSC_renameat2 4507
[  901.272638] shmem_rename2 3172
[  901.272941] shmem_rename2 3176
[  901.274771] vfs_rename 4448 &i-op->rename=0x81190db0
[  901.276033] vfs_rename 4449 error=0
[  901.276377] SYSC_renameat2 4601 error=0
/tmp #
-bash-4.1$ nm vmlinux | grep rename | grep 8120c3f0
ffffffff8120c3f0 T simple_rename
-bash-4.1$

 ok,已经看到函数调用的具体原型。

这个例子中的的renameat2程序是ltp套件中的测试程序,程序会调用renameat2进入内核,而内核会通过vfs调用到具体文件系统的rename接口。

1、ramfs文件系统的inode操作集

148 static const struct inode_operations ramfs_dir_inode_operations = {
149         .create         = ramfs_create,
150         .lookup         = simple_lookup,
151         .link           = simple_link,
152         .unlink         = simple_unlink,
153         .symlink        = ramfs_symlink,
154         .mkdir          = ramfs_mkdir,
155         .rmdir          = simple_rmdir,
156         .mknod          = ramfs_mknod,
157         .rename         = simple_rename,
158 };

262 static struct file_system_type ramfs_fs_type = {
263         .name           = "ramfs",
264         .mount          = ramfs_mount,
265         .kill_sb        = ramfs_kill_sb,
266         .fs_flags       = FS_USERNS_MOUNT,
267 };

 2、tmpfs文件系统的inode操作集

3927 static const struct inode_operations shmem_dir_inode_operations = {
3928 #ifdef CONFIG_TMPFS
3929         .create         = shmem_create,
3930         .lookup         = simple_lookup,
3931         .link           = shmem_link,
3932         .unlink         = shmem_unlink,
3933         .symlink        = shmem_symlink,
3934         .mkdir          = shmem_mkdir,
3935         .rmdir          = shmem_rmdir,
3936         .mknod          = shmem_mknod,
3937         .rename         = shmem_rename2,
3938         .tmpfile        = shmem_tmpfile,
3939 #endif
3940 #ifdef CONFIG_TMPFS_XATTR
3941         .listxattr      = shmem_listxattr,
3942 #endif
3943 #ifdef CONFIG_TMPFS_POSIX_ACL
3944         .setattr        = shmem_setattr,
3945         .set_acl        = simple_set_acl,
3946 #endif
3947 };

3991 static struct file_system_type shmem_fs_type = {
3992         .owner          = THIS_MODULE,
3993         .name           = "tmpfs",
3994         .mount          = shmem_mount,
3995         .kill_sb        = kill_litter_super,
3996         .fs_flags       = FS_USERNS_MOUNT,
3997 };

3、ext4fs文件系统的inode操作集 

3883 const struct inode_operations ext4_dir_inode_operations = {
3884         .create         = ext4_create,
3885         .lookup         = ext4_lookup,
3886         .link           = ext4_link,
3887         .unlink         = ext4_unlink,
3888         .symlink        = ext4_symlink,
3889         .mkdir          = ext4_mkdir,
3890         .rmdir          = ext4_rmdir,
3891         .mknod          = ext4_mknod,
3892         .tmpfile        = ext4_tmpfile,
3893         .rename         = ext4_rename2,
3894         .setattr        = ext4_setattr,
3895         .getattr        = ext4_getattr,
3896         .listxattr      = ext4_listxattr,
3897         .get_acl        = ext4_get_acl,
3898         .set_acl        = ext4_set_acl,
3899         .fiemap         = ext4_fiemap,
3900 };

5790 static struct file_system_type ext4_fs_type = {
5791         .owner          = THIS_MODULE,
5792         .name           = "ext4",
5793         .mount          = ext4_mount,
5794         .kill_sb        = kill_block_super,
5795         .fs_flags       = FS_REQUIRES_DEV,
5796 };
5797 MODULE_ALIAS_FS("ext4");

猜你喜欢

转载自blog.csdn.net/y33988979/article/details/82117620