zoukankan      html  css  js  c++  java
  • Linux内核日志开关

    Linux内核日志开关

    1、让pr_debug能输出

    --- a/kernel/printk/printk.c

    +++ b/kernel/printk/printk.c

    @@ -59,7 +59,7 @@

    /* We show everything that is MOREimportant than this.. */

    #define MINIMUM_CONSOLE_LOGLEVEL 1 /*Minimum loglevel we let people use */

    -#define DEFAULT_CONSOLE_LOGLEVEL 7 /*anything MORE serious than KERN_DEBUG */

    +#define DEFAULT_CONSOLE_LOGLEVEL 8 /*anything MORE serious than KERN_DEBUG */

    int console_printk[4] = {

    DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */

    2、让模块内代码都能输出

    --- a/drivers/of/Makefile

    +++ b/drivers/of/Makefile

    EXTRA_CFLAGS += -DDEBUG

    3、让每个文件输出

    --- a/drivers/of/Makefile

    +++ b/drivers/of/Makefile

    文件include之前加define DEBUG

    或者Makefile里面增加

    pr_debug()
    
        Some files call pr_debug(), which is ordinarily an empty macro that discards
        its arguments at compile time.  To enable debugging output, build the
        appropriate file with -DDEBUG by adding
    
          CFLAGS_[filename].o := -DDEBUG
    
        to the makefile.
    
        For example, to see all attempts to spawn a usermode helper (such as
        /sbin/hotplug), add to lib/Makefile the line:
    
            CFLAGS_kobject_uevent.o := -DDEBUG
    
        Then boot the new kernel, do something that spawns a usermode helper, and
        use the "dmesg" command to view the pr_debug() output.

    4、内核打印控制

    d,lx,ld,,lu,这几个都是输出32位的
    hd,hx,hu,这几个都是输出16位数据的,
    hhd,hhx,hhu,这几个都是输出8位的,
    lld,ll,llu,llx,这几个都是输出64位的,

    ---------------

    如何打开pr_debug调试信息

    如何打开pr_debug调试信息

    以DMA的调试为例,先来看看一个pr_debug函数调用
           pr_debug("%s: %s (%s) ",
                     __func__,
                     chan ? "success" : "fail",
                     chan ? dma_chan_name(chan) : NULL);

    在include/linux/printk.h里找到pr_debug的定义

    /* If you are writing a driver, please use dev_dbg instead */
    #if defined(CONFIG_DYNAMIC_DEBUG)
    /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
    #define pr_debug(fmt, ...)
            dynamic_pr_debug(fmt, ##__VA_ARGS__)
    #elif defined(DEBUG)
    #define pr_debug(fmt, ...)
            printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
    #else
    #define pr_debug(fmt, ...)
            no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
    #endif

    三个判断条件决定pr_debug的用法:
    1.如果定义了CONFIG_DYNAMIC_DEBUG,就使用动态debug机制dynamic_pr_debug();
    2.如果定义了DEBUG,就使用printk(KERN_DEBUG...)
    3.默认情况下,不打印。

    那么要想让kernel乖乖的打印调试信息,就只有两条路可选了:要么动态debug,要么定义DEBUG宏。

    先说一下如何定义DEBUG宏:
    其实在kernel中很多driver已经定义好了这样的选项
    例如,我们经常可以看到这样的配置选项和宏定义:
    (1)DMA Engine debugging(CONFIG_DMADEVICES_DEBUG )
    (2)Power Management Debug Support(CONFIG_PM_DEBUG)
    (3) Enable debug for the B2C2 FlexCop drivers(CONFIG_PCI_DEBUG)

    以DMA为例,在drivers/dma/Makefile中定义了编译选项
    ccflags-$(CONFIG_DMADEVICES_DEBUG)  := -DDEBUG (可在内核config中把该宏打开)
    其作用相当于在drivers/dma/所有子文件定义了宏#define DEBUG

    小伙伴们赶紧把CONFIG_DEBUG选项选上吧,然后重新编译kernel。先别急,这样还不够,
    默认的console级别是7(在kernel/printk/printk.c中定义了#define DEFAULT_CONSOLE_LOGLEVEL 7)
    只有那些级别“小于7”的调试信息才能打印出来,而printk(KERN_DEBUG...)的级别是7,那就还需要提高console打印级别
    如果要查看dma初始化的debug信息,那就直接改代码
    #define DEFAULT_CONSOLE_LOGLEVEL 8
    如果是runtime,可以直接通过printk的sys接口调整打印级别
    $cat /proc/sys/kernel/printk
    7       4       1       7
    $echo 8 > /proc/sys/kernel/printk
    $cat /proc/sys/kernel/printk
    8       4       1       7

    ok,大功告成!

    ps:如果一些driver没有现成的宏可用,开发人员可以自己仿照上述方法,也可以直接在源文件中定义DEBUG宏

    #define DEBUG(宏的作用范围相信我就不用多说了吧,就是从宏定义开始到源文件的末尾结束)

    下面再简单说一下kernel的动态调试
    打开Enable dynamic printk() support(DYNAMIC_DEBUG),那么所有的 pr_debug()/dev_debug() 之类的函数在runtime就可以动态地使用了。
    kernel动态调试提供一个debugfs接口: <debugfs>/dynamic_debug/control 
    这个文件可以用来获取已完成的调试信息列表
    例如你要显示文件'svcsock.c'的1603行内容,你可以这样做:

    nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
                    <debugfs>/dynamic_debug/control  

    // 提供文件svcsock.c所有信息 
    nullarbor:~ # echo -n 'file svcsock.c +p' >
                    <debugfs>/dynamic_debug/control

    如果你想执行多个命令,你需要为每个加入“echo”分割,像这样:

    nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;
    > echo 'file svcsock.c line 1563 +p' > /proc/dprintk

    或者甚至是这样:

    nullarbor:~ # (
    > echo 'file svcsock.c line 1603 +p' ;
    > echo 'file svcsock.c line 1563 +p' ;
    > ) > /proc/dprintk

    file可以替换成module,format等匹配方式,具体用法请参考Documentation/dynamic-debug-howto.txt
    好了,enjoy你的debug之旅吧!

    --------------------

  • 相关阅读:
    svn的安装方法
    在powerDesigner中通过SQL生成pdm
    关于文件下载
    关于ClassPath的思考
    重读Spring之ConfigurationClassPostProcessor-改正错误
    SpringBoot自动装配原理
    SpringMVC之json是怎么传回前端的 @ResponseBody解析
    consumer配置参数之max.poll.interval.ms
    SpringMVC 之处理请求
    使用SpringMVC遇到的坑
  • 原文地址:https://www.cnblogs.com/Ph-one/p/5599677.html
Copyright © 2011-2022 走看看