当前位置: 首页 > news >正文

85 printk 输出丢失数据

前言

问题来自于 chinaunix 社区论坛 

kernel 中读取文件, 只读取到文件部分内容(前1013个字节)

呵呵 看到这个的时候, 我也不太信, 呵呵 但是实际测试一下, 当真如此

然后使用了一个 简单的测试用例 测试了一下

这个问题主要是 printk 的输出的限制 

 

 

测试用例

这里显示模拟的实际情况, 编写的一个测试用例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>    /* for sleep */
#include <linux/wait.h>     /* for wait queue */
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/slab.h>         /* for kmalloc() */
#include <linux/workqueue.h>static int __init shared_workqueue_init(void)
{int i=0;int len = 2048;char *my_data = (char *)kmalloc(len, GFP_KERNEL);for(i=0; i<len; i++) {*(my_data+i) = '6';}pr_info(" before printk ");printk(KERN_INFO "%s", my_data);kfree(my_data);return 0;
}module_init(shared_workqueue_init);static void __exit shared_workqueue_exit(void)
{printk(KERN_INFO "module exit\n ");
}module_exit(shared_workqueue_exit);MODULE_AUTHOR("e665106");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple shared-workqueue Module");
MODULE_ALIAS("a simplest module");

 

这里尝试输出了一个 >= 2048 的一个字符串 my_data

但是实际 输出的结果如下, 然后可以统计一下 这里的 6 的数量为 989 个 

(initramfs) insmod printkOverflow/printkOverflow.ko
[  320.781890] module exit
[  320.781890]
[  336.013758]  before printk
[  336.019556] 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666

 

 

prink 的输出处理

这里的 fmt 为传入的 “%s”, args 为传入的 my_data 的字符串 

text 为输出的一个缓冲, sizeOf(text) 为 992, 计算的方式为 1024 – 32 = 992

 

textbuf 的空间最长长度定义如下, 会保留一部分缓冲用于输出 时间, 颜色信息

 

 

那么也应该是 992 才对, 为什么输出的 6 的数量是 989 呢? 

前两个字符是表示颜色的字符

 

最后一个字符为 字符串的结束符 ‘\0’ 因此 最终有效的 ‘6’ 仅有 992 – 2 -1 为 989 个 

 

 

 

vsnprintf 的测试

测试用例如下, 新建了一个字符串, 长度为 2047

然后使用 vsnprintf 来将其中的 1024 个内容复制到 buff, 然后观察 buff 的相关信息 

这个 在不同的平台上面实现略微有所不同

#include "stdio.h"
#include "stdarg.h"int my_printf(char *buff, int bufLen, const char *fmt, ...);int main() {int i = 0;int srcLen = 2048;char *srcBuf = (char *) malloc(srcLen);for (i = 0; i < srcLen; i++) {*(srcBuf + i) = '6';}*(srcBuf + srcLen - 1) = 0;int bufLen = 1024;char *buff = (char *) malloc(bufLen);int copiedCount = my_printf(buff, bufLen, "%s", srcBuf);printf("%s\n", srcBuf);printf("%s\n", buff);printf("%d\n", copiedCount);return 0;}int my_printf(char *buff, int bufLen, const char *fmt, ...) {va_list ap;va_start(ap, fmt);int copiedCount = vsnprintf(buff, bufLen, "%s", ap);va_end(ap);return copiedCount;
}

 

在 windows 上面执行结果如下 

srcBuf 中 2047 个 ‘6’, 是正确的 

buff 中 1024 个 ‘6’, 并且后面还携带了遗传特殊字符, 这说明 vsnprintf 中未将 buff 的最后一个字节设置为 0

copiedCount 这里是响应的是拷贝出错, 但是数据 依然拷贝到 buff 中了 

6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666����������������
-1

 

在 linux 上面执行结果如下 

srcBuf 中 2047 个 ‘6’, 是正确的 

buff 中 1023 个 ‘6’, buff 中最后一个字节为 0, 因此这里 输出的是 1023 个 ‘6’

copiedCount 这里是响应的是原字符串的长度, 2047

6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
2047

 

但是值得注意的是, 虽然 vsnprintf 名字相同, 参数的传递相同 

但是 这里测试用例的 vsnprintf 和 内核的 vsnprintf 不是同一个 

 

这里测试用例中断的 vsnprintf 实现如下, 是 glibc 的一个实现 

然后实现方式 类似于 printf

 

 

 

 

 

http://www.xdnf.cn/news/1461709.html

相关文章:

  • 分布式专题——1.1 Redis单机、主从、哨兵、集群部署
  • 解决 Apache/WAF SSL 证书链不完整导致的 PKIX path building failed 问题
  • 还在为第三方包 bug 头疼?patch-package 让你轻松打补丁!
  • 时间轮算法在workerman心跳检测中的实战应用
  • leecode kadane算法 解决数组中子数组的最大和,以及环形数组连续子数组的最大和问题
  • Doirs Routine Load
  • PHP:驱动现代Web应用发展的核心力量
  • 【AI产品思路】AI 原型设计工具横评:产品经理视角下的 v0、Bolt 与 Lovable
  • 如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本
  • Python 实现 Markdown 与 Word 高保真互转(含批量转换)
  • Windows 文件资源管理器无法预览文件内容word、ppt、excel、pdf
  • python创建并写入excel文件
  • Go语言的编译和运行过程
  • 【案例】AI语音识别系统的标注分区策略
  • 云计算学习笔记——日志、SELinux、FTP、systemd篇
  • FastGPT源码解析 工作流、知识库、大模型、Agent等核心代码文件梳理
  • es运维常用命令
  • 基于cornerstone3D的dicom影像浏览器 第四章 鼠标实现翻页、放大、移动、窗宽窗位调节
  • 进阶向:Python生成艺术图案(分形、数学曲线)
  • 深度相机详解
  • Spring Boot启动失败从循环依赖到懒加载配置的深度排查指南
  • 《Keil 开发避坑指南:STM32 头文件加载异常与 RTE 配置问题全解决》
  • 【译】GitHub Copilot for Azure(预览版)已经在 Visual Studio 2022 中推出
  • 动物专家?单词测试!基于 TensorFlow+Tkinter 的动物识别系统与动物识别小游戏
  • claude-sonnet4和GLM-4-5-HTML版本迷宫小游戏
  • honmony 中集成 tuanjie/unity
  • 自由学习记录(95)
  • Bug 排查日记:从问题浮现到解决的技术之旅
  • C++ opencv RTSP小工具 RTSP流播放、每一帧保存
  • 爆改YOLOv8 | 即插即用的AKConv让目标检测既轻量又提点