Linux 内核调试之 printk

问题描述:最近这两天再调试 platform 驱动,程序老是有点小问题,得不到自己想要的结果,突然意识到内核调试重要性,重新整理一下 printk 基本用法。内核通过
printk() 输出相关信息,在调用 printk() 函数时必须要指定日志级别。

1、printk 日志等级

在 include/linux/kernel.h 中定义了如下几个日志级别

<span style="font-family:Microsoft YaHei;font-size:12px;">#define	KERN_EMERG	"<0>"	/* 系统崩溃 */
#define	KERN_ALERT	"<1>"	/* 必须紧急处理 */
#define	KERN_CRIT	"<2>"	/* 临界条件,严重的硬软件错误 */
#define	KERN_ERR	        "<3>"     /* 报告错误 */
#define	KERN_WARNING	"<4>"	/* 警告 */
#define	KERN_NOTICE	"<5>"	/* 普通但还是须注意 */
#define	KERN_INFO	"<6>"	/* 信息 */
#define	KERN_DEBUG	"<7>"	/* 调试信息 */</span>

这里也可以看出数值越小,其紧急和严重程度就越高。

接下来,我们来看 kernel/printk.c 文件:

/* printk's without a loglevel use this.. */
#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中更改 */

在 /proc/sys/kernel/printk 会显示4个数值(可由 echo 修改),分别表示

当前控制台日志级别;

未明确指定日志级别的默认消息日志级别;

最小(最高)允许设置的控制台日志级别;

引导时默认的日志级别;

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

系统的日志记录工具有两种主要的:syslog 和 klog。

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

2、printk 输出格式符

如果变量类型是 , 使用 prink 的格式说明符 :

  int                                         %d 或者 %x( 注: %d 是十进制, %x 是十六进制 )

  unsigned int                          %u 或者 %x

  long                                      %ld 或者 %lx

  unsigned long                       %lu 或者 %lx

  long long                              %lld 或者 %llx

  unsigned long long               %llu 或者 %llx

  size_t 
                                  %zu 或者 %zx

  ssize_t                                   %zd 或者 %zx

  原始指针值必须用 %p 输出。

  u64,即(unsigned long log n),必须用 %llu 或者 %llx 输出,如:

  printk("%llu", (unsigned long long)u64_var);

  s64,即(long long),必须用 %lld 或者 %llx 输出,如 :

  printk("%lld", (long long)s64_var);

时间: 2024-09-30 11:14:21

Linux 内核调试之 printk的相关文章

基于FS4412嵌入式系统移植(8) linux内核调试之printk

以下内容主要摘录自<Linux安全体系分析与编程> 1.基本原理 (1)在UBOOT里设置console=ttySAC0或者console=tty1 这里是设置控制终端,tySAC0 表示串口, tty1 表示lcd (2)内核用printk打印 内核就会根据命令行参数来找到对应的硬件操作函数,并将信息通过对应的硬件终端打印出来! 2.printk及控制台的日志级别 函数printk的使用方法和printf相似,用于内核打印消息.printk根据日志级别(loglevel)对消息进行分类. 相

Linux Kernel - Debug Guide (Linux内核调试指南 )

http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和安装 安装交叉编译工具 bin工具集的使用 qemu的使用 initrd.img的原理与制作 x86虚拟调试环境的建立 arm虚拟调试环境的建立 arm开发板调试环

Linux内核调试技术——jprobe使用与实现

前一篇博文介绍了kprobes的原理与kprobe的使用与实现方式,本文介绍kprobes中的第二种探测技术jprobe,它基于kprobe实现,不能在函数的任意位置插入探测点,只能在函数的入口处探测,一般用于监测函数的入参值.本文首先通过一个简单的示例介绍jprobe的使用方式,然后通过源码详细分析jprobe的实现流程. 内核源码:Linux-4.1.x 实验环境:Fedora25(x86_64).树莓派1b 1.jprobe使用实例 使用jprobe探测函数的入参值,需要编写内核模块.同k

linux内核调试指南

linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和安装 安装交叉编译工具 bin工具集的使用 qemu的使用 initrd.img的原理与制作 x86虚拟调试环境的建立 arm虚拟调试环境的建立 arm开发板调试环境的建立 gdb基础 基本命令 gdb之gui gdb技巧 gdb宏 汇编基础--X86篇 用户手册 AT&

Linux内核调试的方式以及工具集锦

CSDN GitHub Linux内核调试的方式以及工具集锦 LDD-LinuxDeviceDrivers/study/debug 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作 因本人技术水平和知识面有限, 内容如有纰漏或者需要修正的地方, 欢迎大家指正, 也欢迎大家提供一些其他好的调试工具以供收录, 鄙人在此谢谢啦 "调试难度本来就是写代码的两倍. 因此, 如果你写代码的时候聪明用尽, 根据定义, 你就没有能耐去调试它了.&qu

Linux内核调试方法总结

一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2  dump_stack() 五  printk() 1  printk函数的健壮性 2  printk函数脆弱之处 3  LOG等级 4  记录缓冲区 5  syslogd/klogd 6  dmesg 7 注意 8 内核printk和日志系统的总体结构 9  动态调试 六  内存调试工具 1  MEMWATCH 2  YAMD

Linux内核调试技术——kretprobe使用与实现

摘自:https://blog.csdn.net/luckyapple1028/article/details/54782659前两篇博文介绍了kprobes探测技术中kprobe和jprobe的使用与实现.本文介绍kprobes中的最后一种探测技术kretprobe,它同样基于kprobe实现,可用于探测函数的返回值以及计算函数执行的耗时.本文首先通过一个简单的示例程序介绍kretprobe的使用方式,然后通过源码分析它是如何实现的. 内核源码:Linux-4.1.x 实验环境:Fedora2

Linux内核调试方法总结之死锁问题分析

死锁问题分析 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务,而且还会占用系统资源,影响其他进程.所以内核中设计了内核死锁检测机制,一旦发现死锁进程,就重启OS,快刀斩乱麻解决问题.之所以使用重启招数,还是在于分布式系统中可以容忍单点崩溃,不能容忍单点进程计算异常,否则进行死锁检测重启OS就得不偿失了. 内核提供自旋锁.信号量等锁形式的工具,具体不再赘述. L

Linux内核调试方法总结之序言

本系列主要介绍Linux内核死机.异常重启类稳定性问题的调试方法. 在Linux系统中,一切皆为文件,而系统运行的载体,是一类特殊的文件,即进程.因此,我尝试从进程的角度分析Linux内核的死机.异常重启等问题.在内核空间,内核本身是一个特权级的进程,它包含一系列系统级线程,维护整个系统内核的运转.在用户空间,有很多用户进程实现不同的功能,它们有的是独立运行,有些相互之间有依赖(同步或者互斥).在32位系统中,内核进程独享3GB~4GB的高1GB内存空间,而每个用户进程则分别占据0GB~3GB的