精华内容
下载资源
问答
  • 内核debugfs使用简介

    2021-01-20 13:36:15
    创建一个debugfs目录: struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); 创建一个debugfs文件: struct dentry *debugfs_create_file(const char *name, umode_t mode, struct ...
  • linux内核 DebugFS

    千次阅读 2017-03-29 16:33:58
    点击打开链接一、简介DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件系统还有procfs和sysfs等,这几种虚拟文件系统都并不实际存储在硬盘上,而是...

    点击打开链接

    一、简介

    DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件系统还有procfs和sysfs等,这几种虚拟文件系统都并不实际存储在硬盘上,而是Linux内核运行起来后才建立起来。

    通常情况下,最常用的内核调试手段是printk。我们在调试时可能需要修改某些内核变量,这种情况下printk就无能为力,而如果为了修改某个值重新编译内核或者驱动又过于低效,此时就需要一个临时的文件系统可以把我们需要关心的数据映射到用户空间。不论是procfs或是sysfs,用它们来实现某些debug的需求,似乎偏离了它们创建的本意。比如procfs,其目的是反映进程的状态信息;而sysfs主要用于Linux设备模型。不论是procfs或是sysfs的接口应该保持相对稳定,因为用户态程序很可能会依赖它们。当然,如果我们只是临时借用procfs或者sysfs来作debug之用,在代码发布之前将相关调试代码删除也无不可。但如果相关的调试借口要在相当长的一段时间内存在于内核之中,就不太适合放在procfs和sysfs里了。故此,debugfs应运而生。

    默认情况下,debugfs会被挂载在目录/sys/kernel/debug之下,如果你的发行版里没有自行挂载,可以用下面命令手动完成:

    mount -t debugfs none /sys/kernel/debug


    二、打开debugfs选项

    要使用debugfs,首先我们要设置一下配置选项CONFIG_DEBUG_FS,可以在config文件中设置CONFIG_DEBUG_FS=y,也可以通过menuconfig来设置

    Kernelhacking --->

                              [*]Debug Filesystem

    并且驱动中使用debugfs需要包含头文件<linux/debugfs.h>,为了在用户态下使用debugfs,必须把它mount到一个目录下


    三、Llinux内核为debugfs提供了非常简洁的API:

    debugfs
    |--mydebug

       |--subdir

          c

       a

       b


    1、创建和撤销目录及文件

    1)structdentry *debugfs_create_dir(constchar*name,structdentry *parent);
    第一个参数是目录的名称,第二个参数是指定这个目录的上级目录,如果是NULL,表示放在debugfs的根目录下
    my_debugfs_root = debugfs_create_dir("mydebug", NULL);
    sub_dir = debugfs_create_dir("subdir", my_debugfs_root);
    debugfs
    |--mydebug
       |--subdir


    2)structdentry *debugfs_create_file(constchar*name, mode_t mode,structdentry *parent,void*data,conststructfile_operations *fops);
    文件c通过自定义的文件操作实现读写
    debugfs
    |--mydebug
       |--subdir
          c
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. static int c_open(struct inode *inode, struct file *filp)  
    2. {  
    3.     filp->private_data = inode->i_private;  
    4.     return 0;  
    5. }  
    6.    
    7. static ssize_t c_read(struct file *filp, char __user *buffer,  
    8.         size_t count, loff_t *ppos)  
    9. {  
    10.     if (*ppos >= 32)  
    11.         return 0;  
    12.     if (*ppos + count > 32)  
    13.         count = 32 - *ppos;  
    14.    
    15.     if (copy_to_user(buffer, hello + *ppos, count))  
    16.         return -EFAULT;  
    17.    
    18.     *ppos += count;  
    19.    
    20.     return count;  
    21. }  
    22.    
    23. static ssize_t c_write(struct file *filp, const char __user *buffer,  
    24.         size_t count, loff_t *ppos)  
    25. {  
    26.     if (*ppos >= 32)  
    27.         return 0;  
    28.     if (*ppos + count > 32)  
    29.         count = 32 - *ppos;  
    30.    
    31.     if (copy_from_user(hello + *ppos, buffer, count))  
    32.         return -EFAULT;  
    33.    
    34.     *ppos += count;  
    35.    
    36.     return count;  
    37. }  
    38.    
    39. struct file_operations c_fops = {  
    40.     .owner = THIS_MODULE,  
    41.     .open = c_open,  
    42.     .read = c_read,  
    43.     .write = c_write,  
    44. };  
    45.    
    46.    
    47. debugfs_create_file("c", 0644, sub_dir, NULL, &c_fops);  

    3)voiddebugfs_remove(structdentry *dentry);
    4)voiddebugfs_remove_recursive(structdentry *dentry);
    在module_exit中,我们要释放创建的数据
    debugfs_remove_recursive(my_debugfs_root);
    这个函数可以帮我们逐步移除每个分配的dentry,如果你想要一个个手动移除,也可以直接调用debugfs_remove

    2、创建单值文件
    1)structdentry *debugfs_create_u8(constchar*name, mode_t mode,structdentry *parent, u8 *value);
    debugfs_create_u8("a", 0644, my_debugfs_root, &a);
    debugfs
    |--mydebug
       |--subdir
       a
    创建的文件名是a,对应内核中的变量名为a,文件属性为0644,可以对文件读写,相当于是对内核变量读写。

    2)structdentry *debugfs_create_u16(constchar*name, mode_t mode,structdentry *parent, u16 *value);
    3)structdentry *debugfs_create_u32(constchar*name, mode_t mode,structdentry *parent, u32 *value);
    4)structdentry *debugfs_create_u64(constchar*name, mode_t mode,structdentry *parent, u64 *value);
    其中,后缀为x8、x16、x32的这三个函数是指debugfs中的数据用十六进制表示。 
    5)structdentry *debugfs_create_x8(constchar*name, mode_t mode,structdentry *parent, u8 *value);
    6)structdentry *debugfs_create_x16(constchar*name, mode_t mode,structdentry *parent, u16 *value);
    7)structdentry *debugfs_create_x32(constchar*name, mode_t mode,structdentry *parent, u32 *value);
    8)structdentry *debugfs_create_size_t(constchar*name, mode_t mode,structdentry *parent,size_t*value);
    9)structdentry *debugfs_create_bool(constchar*name, mode_t mode,structdentry *parent, u32 *value);

    3、创建BLOB文件
    structdebugfs_blob_wrapper {
        void*data;
        unsignedlongsize;
    };
    structdentry *debugfs_create_blob(constchar*name, mode_t mode,structdentry *parent,structdebugfs_blob_wrapper *blob);
    char hello[32] = "hello world!\n";
    struct debugfs_blob_wrapper b;
    b.data = (void *)hello;
    b.size = strlen(hello) + 1;
    debugfs_create_blob("b", 0644, my_debugfs_root, &b);
    debugfs
    |--mydebug
       |--subdir
       b
    需要注意的是blob wrapper定义的数据只能是只读的,在本例中我们将文件b的权限设定为0644,但实际这个文件还是只读的,
    如果试图改写这个文件,系统将提示出错。
    因此,如果我们要对内核数组进行读写动作,blob wrapper就无法满足要求,我们只能自己定义文件操作来实现。

    4、其他
    structdentry *debugfs_rename(structdentry *old_dir,structdentry *old_dentry,structdentry *new_dir,constchar*new_name);
    structdentry *debugfs_create_symlink(constchar*name,structdentry *parent,constchar*target);

    以上部分转自:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html


    三、实例
    这个实例虽然简单,但是融合了如何在debugfs目录下创建文件,并给出了文件的操作方法;
    也说明了如何创建变量文件,并且用户空间读写这个变量文件相当于是在读写内核空间的这个文件对应的变量
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. // dbgfs.c   
    2. /* 
    3.  * (C) 05-07-2012 Yang Honggang (Joseph), Dslab <eagle.rtlinux@gmail.com> 
    4.  */  
    5. #include <linux/debugfs.h>  
    6. #include <linux/module.h>  
    7. #include <linux/mm.h>  
    8. #include <asm/uaccess.h>   
    9.   
    10. struct dentry *parent, *sw, *inf;  
    11. u32 tr_on = 0;  
    12.   
    13. struct my_data_struct {  
    14.     void* data;  
    15.     unsigned long size;  
    16. } mds;  
    17.   
    18. struct page* pg;  
    19.   
    20. static ssize_t data_read(struct file *file, char __user *user_buf,size_t count, loff_t *ppos)  
    21. {  
    22.     unsigned long i;  
    23.     size_t cnt;  
    24.      
    25.     printk("tr_on:%d\n", tr_on);  
    26.     /* If the tracing_on is Y, fill the data buffer with debug info */  
    27.     if (tr_on) {  
    28.         tr_on = 0; /* Automaticlly clear the 'tracing_on' flag */  
    29.                 for (i = 0; i < (mds.size - 11) / 11; i ++) {  
    30.                 sprintf((char*)((char*)mds.data + i * 11 ), "%ld\n", i + 1000000000);  
    31.         }  
    32.           
    33.         /* Copy debug info to userspace */  
    34.         cnt = copy_to_user(user_buf, (const void *)mds.data, mds.size);  
    35.         return (mds.size - cnt);  
    36.     }  
    37.      
    38.     return 0;  
    39. }  
    40.   
    41. const struct file_operations fops =  
    42. {  
    43.         .read = data_read,  
    44. };  
    45.   
    46. static int __init dbgfs_demon_init(void)  
    47. {  
    48.   
    49.     printk("dbgfs init\n");   
    50.     /* Create dbgfs_demon directory in the debugfs root */  
    51.     parent = debugfs_create_dir("dbgfs_demon", NULL);  
    52.     if (!parent)   
    53.     return -1;     
    54.   
    55. //在debugfs目录下创建变量名tracing_on,对应内核中的变量tr_on  
    56.     /* Create a output switch in dbgfs_demon */  
    57.     sw = debugfs_create_bool("tracing_on", S_IRWXU,parent, &tr_on);   
    58.     if (!sw)  
    59.     goto p_out;  
    60.       
    61.     /* Create a file for debug information exporting */  
    62.     mds.size = 4 * 1024;      
    63.     /* Allocate one page for info. storing */  
    64.     pg = alloc_pages(__GFP_HIGHMEM | __GFP_ZERO, 0);  
    65.     /* Covert to Memory address */  
    66.     mds.data = (void*) page_address(pg);  
    67.     if (!pg)  
    68.     goto p_out;  
    69.   
    70. //在debugfs目录下创建文件名data,对应的文件操作为fops里面的read和write方法,  
    71. //通过read函数中从用户空间传来的buf进行相应的处理。  
    72.     inf = debugfs_create_file("data", S_IRUSR,parent, &mds, &fops);  
    73.     if (!inf)  
    74.     goto sw_out;  
    75.   
    76.     return 0;  
    77.   
    78. sw_out:  
    79.     debugfs_remove(sw);  
    80.     __free_pages(pg, 0);  
    81. p_out:  
    82.     debugfs_remove(parent);  
    83.   
    84.     return -1;  
    85. }  
    86.   
    87. static void __exit dbgfs_demon_exit(void)  
    88. {  
    89.   
    90.     if (pg)  
    91.     __free_pages(pg, 0);  
    92.   
    93.     debugfs_remove(inf);  
    94.     debugfs_remove(sw);  
    95.     debugfs_remove(parent);  
    96.     printk("dbgfs exit\n");  
    97.   
    98.     return;  
    99. }  
    100.   
    101. module_init(dbgfs_demon_init);    
    102. module_exit(dbgfs_demon_exit);    
    103. MODULE_LICENSE("GPL");    
    104. MODULE_AUTHOR("Yang Honggang (Joseph) <eagle.rtlinux@gmail.com>");  
    模块会在/sys/kernel/debugfs根目录下创建
    dbgfs_demon/
    |--data
    |--tracing_on
    函数的操作逻辑是,如果tracing_on的值为Y,那么可以从文件data中读出有用的调试信息,
    如果为N,那么读data操作将不会返回任何数据。



    另外还有一个网上找到的debugfs的小例子:http://download.csdn.net/detail/luckywang1103/9369310

    展开全文
  • Android内核Debug相关

    2019-12-30 15:41:54
    打印log printk,查看方式dmesg -w(-w 不退出,持续打印log) 打印方法栈 #include <linux/kprobes.h> #include <asm/traps.h> dump_stack();

    打印log

    printk,查看方式dmesg -w(-w 不退出,持续打印log)

    打印方法栈

    #include <linux/kprobes.h>
    #include <asm/traps.h>
    dump_stack();

    展开全文
  • 内核 DEBUG日志控制

    千次阅读 2018-03-07 11:59:52
    在开发过程中,无可避免的会遇到printk打印信息的输出,在写新功能或... 下面的方法可以对输出进行控制: #undefPRINTD#undefPRINTDD#ifdefFREE_DEBUGG#definePRINTDD(nu,fmt,arg...) printk(KERN_DEBUG"free...

    在开发过程中,无可避免的会遇到printk打印信息的输出,在写新功能或BUG调试的时候我们想看到更多的调试信息,但版本发出后,我们想看到尽可能少的输出信息,那么怎么控制这个呢。。 下面的方法可以对输出进行控制:

     

    #undefPRINTD

    #undefPRINTDD

    #ifdefFREE_DEBUGG

    #definePRINTDD(nu,fmt,arg...) printk(KERN_DEBUG"free:"fmt,##arg)

    #else

    #definePRINTDD(nu,fmt,arg...)

    #endif

     

    #ifdef  FREE_DEBUG

    #definePRINTD(nu,fmt,arg...) \

                  do{ \

                                if(1 == nu) printk(KERN_DEBUG"free:"fmt,##arg); \

                                else if(2 == nu){ \

                                              PRINTDD(nu,fmt,##arg);\

                                }\

                  }while(0)

    #else

    #define PRINTD(nu,fmt,arg...)

    #endif

    其中宏FREE_DEBUG是来控制所有的DEBUG是否输出

    而宏FREE_DEBUGG是来控制部分部分的日志输出

    使用方式:

    比如想打印“”hello“”字符串,并且这个字符串即使在发布的版本中也想打印

    那么  在Makefile中添加EXTRA_CFLAGS =  -DFREE_DEBUG 然后调用

    PRINTD(1,”hello”);

    如果这个字符串你想在调试的时候才输出,在发布版本中不想看到它, 那么就可以使用

    PRINTD(2,”hello”)  在调试的时候打开宏 FREE_DEBUGG 在发布的时候关闭宏FREE_DEBUGG  这样就能对日志的输出进行控制了

    展开全文
  • 内核Debugfs文件系统使用指南

    千次阅读 2019-06-10 22:46:25
    什么是Debugfs文件系统? linux文件系统fs的一种,在kernel space和user space之间...procfs:主要输出系统内核参数和进程信息,目录位于/proc/*,参考http://blog.chinaunix.net/uid-20543672-id-3220151.html ...

    什么是Debugfs文件系统?

    linux文件系统fs的一种,在kernel space和user space之间传递数据,主要是kernel向user输出debug信息。

    与sysfs和procfs的区别

    procfs:主要输出系统内核参数和进程信息,目录位于/proc/*,参考http://blog.chinaunix.net/uid-20543672-id-3220151.html

    sysfs:linux设备模型,根据类型对设备进行分类,目录位于/sys/*,参考https://blog.csdn.net/new_abc/article/details/7555610

    Debugfs的常用数据结构和函数

    debugfs的基本实现方式类似字符设备驱动,通过一个file_operation结构体,源码参考<linux/debugfs.h>

    static const struct file_operations __fops = {				\
    	.owner	 = THIS_MODULE,						\
    	.open	 = __fops ## _open,					\
    	.release = simple_attr_release,					\
    	.read	 = debugfs_attr_read,					\
    	.write	 = debugfs_attr_write,					\
    	.llseek  = no_llseek,						\
    }

    一、创建目录(可省略)

    struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);

    该函数会在parent目录下创建名为name的目录,如果parent为空,则在/sys/kernel/debug/下。

    创建成功后函数返回一个dentry结构体,用于创建和清理debug file。

    dentry结构体参数

    struct dentry {
    	/* RCU lookup touched fields */
    	unsigned int d_flags;		/* protected by d_lock */
    	seqcount_t d_seq;		/* per dentry seqlock */
    	struct hlist_bl_node d_hash;	/* lookup hash list */
    	struct dentry *d_parent;	/* parent directory */
    	struct qstr d_name;
    	struct inode *d_inode;		/* Where the name belongs to - NULL is
    					 * negative */
    	unsigned char d_iname[DNAME_INLINE_LEN];	/* small names */
    
    	/* Ref lookup also touches following */
    	struct lockref d_lockref;	/* per-dentry lock and refcount */
    	const struct dentry_operations *d_op;
    	struct super_block *d_sb;	/* The root of the dentry tree */
    	unsigned long d_time;		/* used by d_revalidate */
    	void *d_fsdata;			/* fs-specific data */
    
    	union {
    		struct list_head d_lru;		/* LRU list */
    		wait_queue_head_t *d_wait;	/* in-lookup ones only */
    	};
    	struct list_head d_child;	/* child of parent list */
    	struct list_head d_subdirs;	/* our children */
    	/*
    	 * d_alias and d_rcu can share memory
    	 */
    	union {
    		struct hlist_node d_alias;	/* inode alias list */
    		struct hlist_bl_node d_in_lookup_hash;	/* only for in-lookup ones */
    	 	struct rcu_head d_rcu;
    	} d_u;
    } __randomize_layout;

    二、创建debugfs file

    struct dentry *debugfs_create_file(const char *name, umode_t mode,
    				       struct dentry *parent, void *data,
    				       const struct file_operations *fops);
    • name:文件名
    • mode:文件的访问权限
    • parent:在哪个目录下创建,即上步创建目录返回的dentry结构体
    • data:数据储存在struct dentry中structinode的i_private中
    • fops:文件操作函数,一般采用seq_file

    创建确定初始大小的file

    struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
    				struct dentry *parent, void *data,
    				const struct file_operations *fops,
    				loff_t file_size);
    • file_size:文件大小

    创建固定长度的file

    struct dentry *debugfs_create_u8(const char *name, umode_t mode,
    				     struct dentry *parent, u8 *value);
    struct dentry *debugfs_create_u16(const char *name, umode_t mode,
    				     struct dentry *parent, u16 *value);
    struct dentry *debugfs_create_u32(const char *name, umode_t mode,
    				     struct dentry *parent, u32 *value);
    struct dentry *debugfs_create_u64(const char *name, umode_t mode,
    				     struct dentry *parent, u64 *value);
    • 文件只包含一个整数,单值文件

    十六进制文件

    struct dentry *debugfs_create_x8(const char *name, umode_t mode,
    				     struct dentry *parent, u8 *value);
    struct dentry *debugfs_create_x16(const char *name, umode_t mode,
    				     struct dentry *parent, u16 *value);
    struct dentry *debugfs_create_x32(const char *name, umode_t mode,
    				     struct dentry *parent, u32 *value);
    struct dentry *debugfs_create_x64(const char *name, umode_t mode,
    				     struct dentry *parent, u64 *value);

    布尔值文件

    struct dentry *debugfs_create_bool(const char *name, umode_t mode,
    				       struct dentry *parent, bool *value);

    另外还能创建包括atomic_t,二进制等类型的file,详见<linux/debugfs.h>

    三、删除debugfs file

    void debugfs_remove(struct dentry *dentry);
    void debugfs_remove_recursive(struct dentry *dentry);

     后者可以递归地删除顶层dentry下的所有file。

     


    内容参考linux-4.19.47\Documentation\filesystems\debugfs.txt

     

     

     

     



     

    展开全文
  • #if 1 #define DEBUG #undef dev_dbg #define dev_dbg dev_err #undef pr_debug #define pr_debug pr_err #endif 在想 debug的c文件开头加上这些即可。
  • echo 0 > /proc/sys/kernel/printk \r 转载于:https://www.cnblogs.com/Xuxiangquan/p/10978228.html
  • /sys/kernel/debug/dynamic_debug/control echo -n "file msm-dai-q6-v2.c +p" > /sys/kernel/debug/dynamic_debug/control echo -n "file soc-dapm.c +p" > /sys/kernel/debug/dynamic_debug/control echo -...
  • 有点空闲时间,让我们来总结一下内核DEBUG中的各个语句吧。随便找个内核驱动,在init函数里面加入如下代码测试:u8 a = 1, b = 0;printk("----------dump stack\n");dump_stack();printk("----------BUG_ON\n");BUG_...
  • AUDIO_DEBUG_PROC_INFO "debuginfo" 30 #define MAX_BUF_WT_LEN 200 // do not bigger than one page size 1024 bytes 31 #define MAX_BUF_RD_LEN 2048 32 33 static struct proc_dir_entry...
  • 内核也是一个大茶几,不过它上面的杯具是一个个的bug。确定bug什么时候被引入是一个很关键的步骤,在这个定位bug的过程中,不论有意或无意,都会很自然地用到二分查找的方法。二分查找法的基本原理对于二分查找法,...
  • Starting program: /home/xbw/debug-kernel/linux-2.6.32.21/linux debug 'debug' is not necessary to gdb UML in skas mode - run 'gdb linux' ........................................
  • Linux内核调试debugfs

    2019-02-18 09:46:06
    DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件系统还有procfs和sysfs等,这几种虚拟文件系统都并不实际存储在硬盘上,而是Linux内核运行起来后才...
  • 调试内核打印debugfs

    2017-01-29 00:11:00
    内核中也不要直接用printk,可以把想查看的数据通过debugfs来查看。 debugfs的用法和sysfs的用法相似。***在注册制好后,路径在/sys/kernel/debug路径下。 使用方法: 添加头文件<linux/debugfs.h&...
  • 内核dynamic_debug调试相关

    千次阅读 2019-09-27 15:00:26
    内核中有用pr_debug及dev_debug的log输出, 可以使用内核动态调试开关来选择。 具体操作如下: 1. make menconfig 使能dynamic_debug相关配置 2. cat /sys/kernel/debug/dynamic_debug/control | grep "dwc3/...
  • Linux 编译debug内核

    2020-12-28 16:54:37
    0x01:下载内核源码 a.官方网站: https://www.kernel.org/ b.ftp服务器下载: http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/ 下载内核源码版本:5.3.1 0x02:编译带调试信息内核做 解压内核代码,我...
  • Debug 内核 Oops

    千次阅读 2013-11-16 03:05:19
    内核的Oops有点像用户态的 段错误(segfaults). 通常,CPU寄存器和调用栈信息会被dump出来。利用这些信息,能够查出来发生问题的代码。 下面一一个例子来说明。 1. 首先,写一个简单的内核模块代码: #include #...
  • Linux内核里的DebugFS

    2018-08-11 15:26:57
    DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件系统还有procfs和sysfs等,这几种虚拟文件系统都并不实际存储在硬盘上,
  • linux内核里的Debugfs

    2014-05-07 16:28:48
    Linux内核里的DebugFS 2011-01-17 23:52 by wwang, 12517 阅读, 6 评论, 收藏, 编辑 DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,025
精华内容 810
关键字:

内核debug