linux内核提供函数dump_stack()来跟踪函数的调用过程,原理是通过打印当前cpu的堆栈的调用函数来显示当前的上下文环境与调用关系;


例:

创建一个混杂设备,并定义read函数。在read中加入dump_stack(),显示read调用关系。结果如下:

[ 1560.465491] CPU: 0 PID: 2759 Comm: cat Tainted: GF          O 3.13.0-32-generic #57-Ubuntu
[ 1560.465494] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
[ 1560.465496]  00000000 00000000 ddf47f58 c1650cd3 dc05e3c0 ddf47f64 e0937010 00000000
[ 1560.465502]  ddf47f88 c1179238 ddf47f98 ddf47fac c1125645 00a000c9 dc05e3c0 00000000
[ 1560.465506]  09431000 ddf47fac c11799a9 ddf47f98 00010000 00000000 00000000 00000003
[ 1560.465511] Call Trace:
[ 1560.465521]  [<c1650cd3>] dump_stack+0x41/0x52
[ 1560.465525]  [<e0937010>] my_read+0x10/0x20 [test]
[ 1560.465529]  [<c1179238>] vfs_read+0x78/0x140
[ 1560.465534]  [<c1125645>] ? SyS_fadvise64_64+0x1e5/0x260
[ 1560.465537]  [<c11799a9>] SyS_read+0x49/0x90
[ 1560.465542]  [<c165efcd>] sysenter_do_call+0x12/0x28


test.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>

int my_read(struct file *file, char __user *user, size_t size, loff_t * loff)
{
        dump_stack();
        printk(KERN_INFO "This is miscdevice read\n");
        return 0;
}

int my_open(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "This is miscdevice open\n");
        return 0;
}

int my_close(struct inode *inode, struct file *file)
{
        printk(KERN_INFO "This is miscdevice close\n");
        return 0;
}

const struct file_operations my_fops = {
        .open = my_open,
        .release = my_close,
        .read = my_read,
};

struct miscdevice  my_misc = {
        .minor = 201,
        .name = "stone",
        .fops = &my_fops,
};

static __init int hello_init(void)
{
        misc_register(&my_misc);
        printk(KERN_ALERT "helloworld!\n");
        return 0;
}

static __exit void hello_exit(void)
{
        misc_deregister(&my_misc);
        printk(KERN_ALERT "helloworld exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stone");



Logo

更多推荐