打印调试技术 printk klogd dmesg(解决打印信息的问题)

4.2.1. printk
#include
printk(KERN_CRIT"error %s,%i",__FILE__,__LINE__);
注:
1). printk函数中能够指定优先级,假如printk没有指定优先级,采用默认优先级,DEFAULT_MESSAGE_LEVEL,其值在
    头文档linux/printk.h中宏定义了8个级别,0-8从高到低分别是:
    KERN_EMERG, KERNEL_ALERT, KERN_CRIT, KERN_ERR, KERN_WARNING, KERN_NOTICE, KERN_INFO, KERN_DEBUG
2). 当printk指定的优先级小于指定的控制台优先级console_loglevel时,调试消息就显示在控制台虚拟终端。
  缺省的console_loglevel值是DEFAULT_CONSOLE_LOGLEVEL。
  .也能够使用系统调用sys_syslog或klogd -c来修改console_loglevel值。
scull  .在新版本中,也能够直接通过文档/proc/sys/kernel/printk修改,这个文档包含4个整数值,前两个表示系统当前的优先级和缺省优先级。
    能够直接echo 8 > /proc/sys/kernel/printk
  .也能够指定显示在其他控制台,通过调用ioctl(TIOCLINUX)或shell命令setconsole来配置。
  .假如运行了klogd和syslogd,则printk打印到var/log/messages。
. 用打印调试
最常用的调试技术是监视, 在应用程序编程当中是通过在合适的地方调用 printf 来实现. 在你调试内核代码时, 你可以通过 printk 来达到这个目的.
一个不同是 printk 允许你根据消息的严重程度对其分类, 通过附加不同的记录级别或者优先级在消息上. 你常常用一个宏定义来指示记录级别. 例如, KERN_INFO, 我们之前曾在一些打印语句的前面看到过, 是消息记录级别的一种可能值. 记录宏定义扩展成一个字串, 在编译时与消息文本连接在一起; 这就是为什么下面的在优先级和格式串之间没有逗号的原因. 这里有 2 个 printk 命令的例子, 一个调试消息, 一个紧急消息:
printk(KERN_DEBUG "Here I am: %s:%i/n", __FILE__, __LINE__);
printk(KERN_CRIT "I'm trashed; giving up on %p/n", ptr);

有 8 种可能的记录字串, 在头文件 <linux/kernel.h> 里定义; 我们按照严重性递减的顺序列出它们:
KERN_EMERG
用于紧急消息, 常常是那些崩溃前的消息.
KERN_ALERT
需要立刻动作的情形.
KERN_CRIT
严重情况, 常常与严重的硬件或者软件失效有关.

下面是全部程序. 应当使用一个参数来指定用以接收消息的控制台的编号.
int main(int argc, char **argv)
{
    char bytes[2] = {11,0}; /* 11 is the TIOCLINUX cmd number */
    if (argc==2) bytes[1] = atoi(argv[1]); /* the chosen console */
    else {
        fprintf(stderr, "%s: need a single arg/n",argv[0]); exit(1); } if (ioctl(STDIN_FILENO, TIOCLINUX, bytes)<0) { /* use stdin */
        fprintf(stderr,"%s: ioctl(stdin, TIOCLINUX): %s/n",
                argv[0], strerror(errno));
        exit(1);
    }
    exit(0);
}

setconsole 使用特殊的 ioctl 命令 TIOCLINUX, 来实现特定于 linux 的功能. 为使用 TIOCLINUX, 你传递它一个指向字节数组的指针作为参数. 数组的第一个字节是一个数, 指定需要的子命令, 下面的字节是特对于子命令的. 在 setconsole 里, 使用子命令 11, 下一个字节(存于 bytes[1])指定虚拟控制台. TIOCLINUX 的完整描述在内核源码的 drivers/char/tty_io.c 里.
4.2.3. 消息是如何记录的
printk 函数将消息写入一个 __LOG_BUF_LEN 字节长的环形缓存, 长度值从 4 KB 到 1 MB, 由配置内核时选择. 这个函数接着唤醒任何在等待消息的进程, 就是说, 任何在系统调用中睡眠或者在读取 /proc/kmsg 的进程. 这 2 个日志引擎的接口几乎是等同的, 但是注意, 从 /proc/kmsg 中读取是从日志缓存中消费数据, 然而 syslog 系统调用能够选择地在返回日志数据地同时保留它给其他进程. 通常, 读取 /proc 文件容易些并且是 klogd 的缺省做法. dmesg 命令可用来查看缓存的内容, 不会冲掉它; 实际上, 这个命令将缓存区的整个内容返回给 stdout, 不管它是否已经被读过.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。