Linux的内核空间中的日志打印函数printk的详解;如果设置`printk` 函数的默认日志级别和是否输出到终端控制台

news2025/1/10 22:08:18

引言

首先,要知道,内核空间是没有printf函数的,printf函数是是用户空间的标准 I/O 函数,而不是内核空间中的。

所以在运行于内核空间的程序中(比如驱动程序),是不能使用printf函数的,但有时候我们又需要打印输出一些信息,怎么办呢?

此时通常大家会选用内核中的printk函数,其详细介绍下:

printk 是 Linux 内核中用于打印日志信息的核心函数。它是内核日志系统的基础,允许开发者将信息写入内核环形缓冲区,供调试或系统管理使用。


printk函数的详细介绍

printk 函数的原型

int printk(const char *fmt, ...);
  • 返回值
    返回实际写入缓冲区的字符数。

  • 参数

    • fmt
      一个格式化字符串,类似于 printf 的格式说明符。它支持大多数标准 C 格式化选项(如 %d%s%x 等),也支持一些特定于内核的格式扩展。
    • ...
      可变参数,提供给格式化字符串使用的具体数据。

printk 函数的日志级别与日志级别前缀

printk 的格式字符串可以包含一个 日志级别前缀,用于指定消息的重要性。这些日志级别以宏的形式定义:

宏名描述数值示例
KERN_EMERG紧急:系统不可用0"<0>"
KERN_ALERT警报:需要立即采取行动1"<1>"
KERN_CRIT严重情况2"<2>"
KERN_ERR错误3"<3>"
KERN_WARNING警告4"<4>"
KERN_NOTICE通知:重要但非错误5"<5>"
KERN_INFO信息6"<6>"
KERN_DEBUG调试信息,仅用于开发7"<7>"

示例:

printk(KERN_ERR "Error occurred: %d\n", error_code);

上述代码将打印一条错误信息到内核日志中,并标记为错误级别。


printk 函数的几个使用示例

  1. 简单打印
    不带日志级别的调用将使用默认日志级别(default_message_loglevel)。
printk("Hello, kernel world!\n");
  1. 带日志级别
    明确指定日志的重要性。

    printk(KERN_INFO "System initialized successfully\n");
    
  2. 格式化字符串
    支持标准格式说明符。

    int value = 42;
    printk(KERN_DEBUG "Debug value: %d\n", value);
    

printk 函数的日志输出到哪里?

  1. 内核环形缓冲区
    printk 的信息会被写入内核的环形缓冲区,可以通过 dmesg/var/log/messages 查看。

  2. 控制台输出
    日志输出到控制台的行为由 /proc/sys/kernel/printkconsole_loglevel 控制。只有日志级别小于等于 console_loglevel 的消息会被打印到控制台。


printk 函数适应内核的格式控制扩展

内核的 printk 支持一些标准 printf 中没有的扩展:

  • 指针打印

    • %p: 打印指针地址
    • %pK: 打印指针地址,受安全保护
    • %px: 指针以十六进制打印
  • 内核特定对象

    • %pf: 打印函数名称
    • %ps: 打印内核符号
  • 定制输出

    • %pb: 位掩码
    • %ph: 打印十六进制数组

示例:

void *ptr = &some_variable;
printk("Pointer address: %p\n", ptr);

使用printk 函数的注意事项

  1. 性能开销
    过多的 printk 调用会增加内核日志的处理负担,影响性能。特别是在高频路径中应避免大量日志输出。

  2. 同步与中断上下文

    • printk 是线程安全的,但在中断上下文中调用可能引发延迟问题。
    • 从 Linux 3.x 起,printk 的行为被优化以减少中断阻塞,但在复杂场景下仍需注意。
  3. 调试日志
    调试信息通常使用 KERN_DEBUG 级别,并配合动态调试机制启用或禁用:

    echo 'module driver_name +p' > /sys/kernel/debug/dynamic_debug/control
    
  4. 控制好控制台的日志级别
    设置过高(如 7)会导致大量调试信息输出到终端,可能影响可读性。
    一般情况下,推荐使用较低级别(如 4 或 3)以减少干扰。

如果设置printk 函数的默认日志级别和是否输出到终端控制台

不管怎么样,printk 函数的日志都会写到内核的环形缓冲区,可以通过命令 dmesg/var/log/messages 查看。
比如下面这个:

dmesg

在这里插入图片描述
但不一定能显示到我们的终端控制台中,如果没有输出到终端中,而又想输出其信息到终端中,请看下面的内容中。

在Linux系统中,/proc/sys/kernel/printk文件中记录了printk的日志级别的相关配置信息,主要就与终端控制台有与。

这个文件包含四个数值,依次表示:

  1. console_loglevel 当前终端控制台打印的日志级别。日志级别小于或等于该值的消息会被打印到控制台。
  2. default_message_loglevel 默认的日志级别。如果 printk 函数被调用时没有指定日志级别前缀,将使用该值作为printk 函数输出的日志信息的日志级别。
  3. minimum_console_loglevel 终端控制台的最低日志级别阈值。如果设置的 console_loglevel 小于该值,那么console_loglevel的值将被提升到此值。
  4. default_console_loglevel 系统启动时的默认终端控制台日志级别。

我们可以修改这几个值实现将一些没有打印显示到终端控制台上的信息显示出来。

我们可以用下面这条命令查看文件/proc/sys/kernel/printk的当前值:

cat /proc/sys/kernel/printk

运行结果如下:
在这里插入图片描述
这是默认值,可见默认情况下终端上只显示级别为警告以下的日志信息:
在这里插入图片描述
如果我们要显示所有的日志信息,显然只需要修改值为7 4 1 7就能打印所有的日志信息到终端上了。

以下是修改方法:

1 临时修改

echo "7 4 1 7" > /proc/sys/kernel/printk

运行上面的 echo 命令后,设置会立即生效,但重启后会恢复默认值,如果想恢复默认值,可值行下面的命令:

echo "4 4 1 4" > /proc/sys/kernel/printk

2 永久修改
如果希望永久修改,可以将设置写入 /etc/sysctl.conf 或创建启动脚本。

方法 1:编辑 sysctl.conf
在文件 /etc/sysctl.conf 中添加:

kernel.printk = 7 4 1 7

然后运行:

sysctl -p

方法 2:添加启动脚本
创建或编辑脚本 /etc/rc.local 或其他系统初始化脚本,添加:

echo "7 4 1 7" > /proc/sys/kernel/printk

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2274569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python编程实例-特征向量与特征值编程实现

特征向量与特征值编程实现 文章目录 特征向量与特征值编程实现1、什么是特征向量2、特征向量背后的直觉3、为什么特征向量很重要?4、如何计算特征向量?4、特征向量Python实现5、可视化特征向量6、总结线性代数是许多高级数学概念的基石,广泛应用于数据科学、机器学习、计算机…

202-01-06 Unity 使用 Tip1 —— UnityHub 模块卸载重装

文章目录 1 卸载模块2 更新配置文件3 重启 UnityHub 起因&#xff1a; ​ WebGL 平台打包程序报错&#xff0c;懒得修复了&#xff0c;因此粗暴地删了重装。但是 UnityHub 不支持卸载模块&#xff0c;因此手动配置。 1 卸载模块 ​ 以 Unity 6000.0.26f1c1 为例&#xff0c;其…

Git的简单介绍与如何安装Git

文章目录 前言一、初始git1.git是什么2.为什么要使用git(出现的问题)3.git是如何解决问题的 二、git的安装与卸载1.centos系统2.ubuntu系统3.windows 三、搭建git本地环境1.创建git本地仓库2.配置用户信息 总结 前言 本文简单引入git的相关内容。 一、初始git 1.git是什么 g…

Linux 进程入门:带你走进操作系统的核心地带(1)

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 在 Linux 操作系…

C#版OpenCv常用函数大全

OpenCvSharp 是 OpenCV 的NET封装&#xff0c;提供了丰富的图像处理和计算机视觉功能。以下是一些常用函数及其详细说明。 1. 图像读取与显示 Cv2.ImRead 功能&#xff1a;读取图像文件并返回一个 Mat 对象。用法&#xff1a;Mat image Cv2.ImRead("path/to/image.jpg&…

【初阶数据结构】线性表之单链表

文章目录 前言 一、单链表的概念与结构 1.概念 2.结点 3.性质 二、实现单链表 1.结构的定义 2.链表的打印和结点的申请 3.单链表的尾插和头插 4.单链表的尾删和头删 5.单链表的查找 6.指定位置之前插入数据和指定位置之后插入数据 7.删除pos结点和删除pos之后的结…

DB-Engines Ranking 2025年1月数据库排行

DB-Engines Ranking 2025年1月数据库排行 DB-Engines排名根据数据库管理系统的受欢迎程度进行排名。排名每月更新一次。 2025年1月&#xff0c;共有423个数据库进入排行。 排行榜 Oracle Oracle 连续三月稳居榜首&#xff0c;排名稳定。2025 年 1 月分数较上月增 5.03&#x…

Hadoop3.x 万字解析,从入门到剖析源码

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

鸿蒙的APP真机调试以及发布

目录&#xff1a; 1、创建好鸿蒙项目2、创建AGC项目3、实现自动签名3.1、手动方式创建签名文件和密码 4、运行项目5、无线真机调试 1、创建好鸿蒙项目 2、创建AGC项目 &#xff08;1&#xff09;在File->Project Structure->Project->Signing Configs中进行登录。(未…

Swin Transformer模型详解(附pytorch实现)

写在前面 Swin Transformer&#xff08;Shifted Window Transformer&#xff09;是一种新颖的视觉Transformer模型&#xff0c;在2021年由微软亚洲研究院提出。这一模型提出了一种基于局部窗口的自注意力机制&#xff0c;显著改善了Vision Transformer&#xff08;ViT&#xf…

穷举vs暴搜vs深搜vs回溯vs剪枝系列一>字母大小写全排列

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; private List<String> ret;private StringBuffer path;public List<String> letterCasePermutation(String s) {ret new ArrayList<>();path new StringBuffer();dfs(s,0);return ret;}private voi…

LabVIEW软件侵权分析与应对

问&#xff1a;如果涉及到LabVIEW软件的仿制或模仿&#xff0c;特别是在功能、界面等方面&#xff0c;如何判断是否构成侵权&#xff1f;该如何应对&#xff1f; 答&#xff1a;LabVIEW软件的侵权问题&#xff0c;尤其是在涉及到仿制或模仿其功能、界面、设计等方面&#xff0…

玩转 JMeter:Random Order Controller让测试“乱”出花样

嘿&#xff0c;各位性能测试的小伙伴们&#xff01;今天咱要来唠唠 JMeter 里超级有趣又超实用的 Random Order Controller&#xff08;随机顺序控制器&#xff09;&#xff0c;它就像是性能测试这场大戏里的“魔术棒”&#xff0c;轻轻一挥&#xff0c;就能让测试场景变得千变…

探秘MetaGPT:革新软件开发的多智能体框架(22/30)

一、MetaGPT 引发的 AI 变革浪潮 近年来&#xff0c;人工智能大模型领域取得了令人瞩目的进展&#xff0c;GPT-3、GPT-4、PaLM 等模型展现出了惊人的自然语言处理能力&#xff0c;仿佛为 AI 世界打开了一扇通往无限可能的大门。它们能够生成流畅的文本、回答复杂的问题、进行创…

01、Redis初认识

一、简介 Redis&#xff0c;Remote Dictionary Server &#xff0c;远程字典服务。它是由一个意大利人使用C语言开发的&#xff0c;支持网络、可基于内存也可以持久化的日志型、NoSQL内存数据库&#xff0c;其提供了多种语言的API。 为什么把Reids称为字典服务&#xff1f; …

【2025 Rust学习 --- 10 运算符重载】

重载操作符 算术运算符与按位运算符 Rust 中&#xff0c;表达式 a b 实际上是 a.add(b) 的简写形式&#xff0c;也就是对标准库 中 std::ops::Add 特型的 add 方法的调用。Rust 的标准数值类型都实现了 std::ops::Add。 trait Add<Rhs Self> {type Output;fn add(se…

node-sass@4.14.1报错的最终解决方案分享

输入npm i全安装文件所需的依赖的时候&#xff0c;博主是使用sass去书写的&#xff0c;使用的是node-sass4.14.1和sass-loader7.3.1的版本的&#xff0c;安装的时候老是出现错误&#xff0c; node-sass4.14.1版本不再被支持的原因 node-sass 是一个基于 LibSass 的 Node.js 绑…

LabVIEW大数据有什么应用场景?

LabVIEW在处理大数据时主要依赖于其强大的数据采集、信号处理、控制、以及实时系统的功能。以下是一些典型的应用场景&#xff1a; ​ 1. 工业自动化与制造 数据采集与监控&#xff1a;在生产线上&#xff0c;LabVIEW可以用来收集大量的传感器数据&#xff08;如温度、压力、湿…

深入理解Mybatis原理》MyBatis的sqlSessi

sqlSessionFactory 与 SqlSession 正如其名&#xff0c;Sqlsession对应着一次数据库会话。由于数据库会话不是永久的&#xff0c;因此Sqlsession的生命周期也不应该是永久的&#xff0c;相反&#xff0c;在你每次访问数据库时都需要创建它&#xff08;当然并不是说在Sqlsession…

【OAuth2系列】如何使用OAuth 2.0实现安全授权?详解四种授权方式

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 【OAuth2系列】集成微…