LINUX内核调试

LINUX内核调试

  • BUG_ON and BUG

    在内核调试中用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。其会引发oops,导致栈的回溯和错误信息打印

    BUG()使用:

    if (bad_thing)
      BUG();
    

    但是常用BUG_ON()

    BUG_ON(bad_thing);
    
  • WARN_ON

    会调用dump_stack,打印堆栈信息,但不会OOPS

    #define WARN_ON(condition)do{
      if(unlikely(condition)!=0){
          printk("Badness in %s at %s:%d/n", __FUNCTION__, __FILE__, __LINE__);
          dump_stack();
      }
    }while(0)
    
  • dump_stack

    作用:

    ​ 输出当前CPU调用的call stack,它只在终端上打印寄存器上下文和函数跟踪线索

    实现:

    	linux/lib/dump_stack.c
        void dump_stack(void)
    
  • panic

    作用:

    ​ 利用panic()引发更严重错误,调用panic()不但会打印错误信息而且还会挂起整个系统,个平台实现不同

    实现:

    	linux/kernel/painc.c
    
  • printk

    类似于printf在内核中输出相关信息,使用如下:

    printk("Hello, World\n"); //未指定级别,采用默认级别输出
    printk(KERN_XXXX "Hello, world");// 注意KERN_XXX后没有逗号
    
    • printk日志级别:
    kernel/printk.c
    #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
    /* 因此,如果未在 printk() 中指定日志级别,系统将默认采用4级 */
    /* We show everything that is MORE important than this.. */
    #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
    #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
    DECLARE_WAIT_QUEUE_HEAD(log_wait);
    int console_printk[4] = {
    	DEFAULT_CONSOLE_LOGLEVEL,	/* console_loglevel */ //当前控制台日志级别
    	DEFAULT_MESSAGE_LOGLEVEL,	/* default_message_loglevel */ //未明确指定日志级别的默认消息日志级别;
    	MINIMUM_CONSOLE_LOGLEVEL,	/* minimum_console_loglevel */ //最小(最高)允许设置的控制台日志级别;
    	DEFAULT_CONSOLE_LOGLEVEL,	/* default_console_loglevel */ //引导时默认的日志级别;
    };
    /* 这4组数字可以在/proc/sys/kernel/printk中更改 */
    

    printk()中指定的级别 (数值上)小于 当前控制台日志级别(前面说过,数值越小,严重性越高)时,printk 的信息(要有\n符)就会在控制台上显示。但无论当前控制台日志级别是何值,通过 dmesg 总能查看。

    • 系统日志记录工具:syslog and log

      syslog 用于执行系统日志记录活动,系统进程显示为 syslogd。配置文件是/etc/syslog.conf。如果在配置文件中把kern.*这一行前的#号去掉,那么printk的信息也会输出到控制台。其守护进程是syslogd。syslogd 进程从一组日志源(如 /dev/log 和 /dev/klog )中读取数据,并按照 /etc/syslog.conf 中的说明处理这些日志消息。

      klog 未使用过,未知。

      系统日志文件保存在 /var/log/ 目录下,比较重要的四个日志文件:messages,kern.log,syslog,debug。

      kern.log,syslog:一般会记录所有级别的日志

      messages:得到的是比控制台日志级别低的日志

      debug:得到的级别是7的日志

    • 内核八种日志级别

      linux/kernel.h
      #define KERN_EMERG    "<0>"    /* system is unusable */
      #define KERN_ALERT    "<1>"    /* action must be taken immediately */
      #define KERN_CRIT     "<2>"    /* critical conditions */
      #define KERN_ERR      "<3>"    /* error conditions */
      #define KERN_WARNING  "<4>"    /* warning conditions */
      #define KERN_NOTICE   "<5>"    /* normal but significant */
      #define KERN_INFO     "<6>"    /* informational */
      #define KERN_DEBUG    "<7>"    /* debug-level messages */
      
  • current

    current指针指向当前运行的进程,内核代码可以通过current来使用进程的特定信息,如:

    printK(KERN_INFO "the process is comm %s pid %d uid %d \n", current->cred->uid.val, current->tgid, current->comm); //comm 当前进程执行的程序文件的基本名称
    

你可能感兴趣的:(Linux)