简图记录-驱动debug之打印总结(printk、dmesg、logcat)

2023-10-31

简图记录总结~

        在驱动开发过程中,常会用到一些打印做问题定位,无论是提前设计或者调试过程中添加,打印都是一种常用的手段。以下为打印相关问题总结。

一、常见驱动打印的添加与查看。

1、内核打印printk

    概念:printk是内核中根据日志级别向控制台输出显示的函数

    用法:用法为printk(消息级别"a=%d\n",a);和printf用法类似。消息级别可省略。消息级别定义参考(0:系统崩溃前、1:系统必须响应的错误处理、2:严重错误、3:一般错误、4:警告、5:提醒、6:提示信息、7:调试信息)

    查看打印等级:使用cat /proc/sys/kernel/printk---->7 4 1 7;第一个等级7表示 控制台当前日志级别(必须要更高的级别才能打印出来);第二个等级4表示默认的消息级别(当printk没有指定打印等级时默认的打印等级);第三个等级1表示最低控制台级别;第四个等级7表示默认中断控制级别;

    设置打印等级:echo 目标级别 >/proc/sys/kernel/printk;

    常见无法打印原因:1、打印级别低于系统设置 2、控制台输出未指定到串口上(boot下bootargs中未设置控制台到串口,如console=ttySAC0;kernel下可以通过cat /proc/cmdline查看bootargs)

2、查看内核缓存打印buffer信息dmesg

    概念:linux系统中用于查看内核ringbuffer的信息(开机信息和printk信息都可以查看)

    用法:(1)直接输入dmesg,打印buffer中缓存所有信息,利用管道组合grep可以查找带XXX信息打印,dmesg | grep XXX ;(2)dmesg -C 显示的同时清空buffer数据,重新开始记录 (3)dmesg -n 打印级别,设置记录控制台输出最低级别

3、Android环境下日志控制logcat(用户态打印)

    概念:Android环境下可以通过logcat进行用户态的打印控制;

    用法:(1)直接输入logcat,默认持续打印所有信息(会阻塞输入),同样可以配合管道和grep指定输出打印,如logcat | grep XXX;(2)logcat -d,打印一次缓存信息到控制台输出(非阻塞);(3)logcat -c,清空打印缓存信息;(4)logcat 模块1:指定打印等级 模块2:指定打印等级,可以选择性的约束指定模块输出等级;

二、常见打印调试技巧

1、利用编译宏添加通用打印信息

    如 __LINE__行号、__FUNCTION__函数名

2、通过current指针打印进程上下文信息

在用户态或者内核态的进程上下问中利用current信息,打印当前进程号和进程名:printk("the process name=%s pid=%i\n",current->comm,current->pid);

3、打印函数调用堆栈信息

    (1)内核态直接在指定调用处添加dump_stack();

    (2)用户态C/C++用系统调用打印,参考实例如下(注意编译时带-rdynamic把符号带入动态链接标,否则只打印地址无 函数名称)

void mybacktrace()
{
    void *buffer[100];
    char **str=NULL;
    int i=0;
    int ptr_num = backtrace(buffer,100);//获取指定最大100个堆栈信息;
    str = backtrace_symbols(buffer,ptr_num);//转化为字符串
    if (NULL == str)return;
    for(i=0p;i<ptr_num;i++)printf("%s\n",str[i]);
    free(str);
}

    (3)用户态java代码添加,利用Exception对象

Exception e = new Exception("***dump stack****");
e.printStackTrace();

三、常见打印注意事项

1、注意打印会引入延时

特别是在中断等对延时敏感场景,打印信息更要简洁明了。。(调试一些耗时敏感的地方一定要注意打印注释掉后是否还符合预期)

2、频繁密集内核打印(如中断)可能挂死系统

不要一直在中断打印大量信息,在中断中过多打印信息会导致过长耗时引起系统响应缓慢、丢中断、甚至挂死系统等问题可以在状态变化时打印(可以加入计数信息),或者计数降频。

3、用户态和内核态打印是并发的

用户态和内核态打印是并发输出的,如果打印位置接近会出现A打印被B打印中断后继续输出甚至覆盖的的情况,在设计打印的时候要留意这一点。或者 使用过程中,直接把内核打印放到后台通过dmesg查看 并使用telnet循环抓取,用户态 直接串口输出记录(确定是无法体现两者同步关系)。

四、打印实现分析:

1、变长参数

     概念:C语言规定变长参数至少存在一个明确的参数,且变长参数必须处在所有参数最后,如:

        int printf(const char *format,...);--->尾部的...表示占位符

    实现参考(用man查看帮助)

        void va_start(va_list ap,last);在最开始变参处理前调用,ap指向最后一个明确参数,取得第一个变参起始地址

        [type] va_arg(va_list ap, [type]);每次调用返回ap指向type类型数据,并将ap指向下一个参数地址

        void va_end(va_list ap);结束变参访用调用(常为空)   

typedef char* va_list;
#define va_size(type)\
    (((sizeof(type)+sizeof(long)-1/sizeof(long)*sizeof(long)) //引入long为编译对齐处理
#define va_start(ap,last)\
((ap)=(va_list)&(last)+va_size(last))
#define va_arg(ap,type)\
(*(type*)((ap)+=va_size(type),(ap)-va_size(type)))
#define va_end(ap)

    变参用法

//使用va_arg逐个取出指定类型,打印n个int型变参
void test_print(int n,...)
{
   int i=0;
   va_list ap;
   va_start(ap,n);
   for (i=0;i<n;i++)
   {
       int tmp = va_arg(ap, int);
       printf("%d num=%d\n",i,tmp);
   }
   va_end(ap)
}
\\结合vsprintf获取字符串打印,制作自己的打印函数
void my_printf(char *fmt,...)
{
   char tmp[100];
   va_list ap;
   va_start(ap,fmt);
   vsprintf(tmp,fmt,ap);
   va_end(ap);
   printf("%s\n",tmp);
}

2、C库printf族函数分析

/*1.<stdio.h>相关打印函数*/
int printf(const *fmt,...);//定义变参,使用vsprintf将变参转化为字符串,再利用终端write向标准输出写数据打印
int fprintf(FILE *stream,const *fmt,...);//定义变参,使用vfprintf将变参输出到文件
int sprintf(char *str,const *fmt,...);//定义变参,使用svprintf将变参转化字符串到buffer中
int snprintf(char *str,size_t size ,const *fmt,...);//定义变参,使用svnprintf将变参转化字符串到buffer中
/*2.<stdarg.h>相关变参处理函数*/
int vprintf(const *fmt,va_list ap);//利用vsprintf将变参转化为字符串,再利用fwrite向标准输出写数据打印
int vfprintf(FILE *stream,const *fmt,va_list ap);//使用vsnprintf将变参转化字符串,并同fwrite将buffer写入文件
int vsprintf(char *str,const *fmt,va_list ap);//解析fmt格式信息和变参ap拼接生成字符串
int svnprintf(char *str,size_t size , const *fmt,...);//类似vsprintf,加入长度校验

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简图记录-驱动debug之打印总结(printk、dmesg、logcat) 的相关文章

  • 初识C语言:一篇文章解决基础的操作符(前置++与后置++的区别)

    目录 一 算术操作符 二 关系操作符 三 赋值操作符 四 自增 自减操作符 前言 总结 前言 1 加法运算符 加法运算符为双目运算符 即应有两个量参与加法运算 右结合性 2 减法运算符 减法运算符为双目运算符 但 也可作负值运算符 此时为单
  • ARM寻址方式

    所谓寻址方式就是处理器根据指令中给出的地址信息来寻找物理地址的方式 ARM处理器的寻址方式 目前ARM处理器支持9种寻址方式 分别是立即数寻址 寄存器寻址 寄存器偏移寻址 寄存器间接寻址 基址变址寻址 多寄存器寻址 相对寻址 堆栈寻址和块拷
  • 自定义规则 Collections.sort() 对 List 排序

    一 Collections sort 与Arrays sort 的比较 Collections sort 该算法是一个经过修改的合并排序算法 其中 如果低子列表中的最高元素效益高子列表中的最低元素 则忽略合并 此算法可提供保证的N log
  • 工作日记NO.12

    后续工作内容 1 尝试编译WINDOWS工程 2 尝试编译LINUX工程 3 根据LINUX工程尝试编译 编写 emscripten工程 今日完成 1 makefile规则 2 libdwg的makefile in makefile am研
  • 一些常用的第三方框架之Fresco下篇

    Fresco的使用 1 gitHub下载依赖库或者jar包 Anroid Studio可以通过compile方式加载 compile com facebook fresco fresco 0 8 1 2 添加网络权限 uses permis
  • spring cloud(四) Eureka配置Httpbasic验证+Eureka配置详解

    目录 spring cloud 一 从一个简单的springboot服务开始 spring cloud 二 起步 集成Eureka服务发现 spring cloud 三 Eureka高可用性 Feign声明式Rest客户端 spring c
  • C# 线程浅谈(三)

    这篇讲线程锁 lock得概念 什么是锁 为什么用锁 做个栗子 俩个线程同时访问一个int对象 一个线程 一个线程 都1W次 那么这个数 不管怎么样 最后都是0 class TaskDom int count 0 public void St
  • 为什么64位计算机CPU架构叫amd64

    x86 1978 年 6 月 Intel 发布了新款 16 位微处理器 8086 开创了一个全新时代 x86 架构由此诞生 x86 架构指的是特定微处理器执行的计算机语言指令集 定义了芯片的基本使用规则 事实上 8086 处理器发布之初并没
  • OpenCV学习日志_2020.10.26_面向Python的OpenCV入门

    日期 2020 10 26 主题 面向Python的OpenCV入门 内容 在Anaconda上安装配置OpenCV 学习图像处理基本操作 以下为具体代码 import cv2 1 读取静态图像 retval cv2 imread file
  • Dell服务器中Lsiutil命令常见使用

    前言 Dell服务器MegaCli命令只返回Exit Code 0x00问题分析 SAS 6i R的raid信息用MegaCli64命令就获取不到呢 SAS 6 iR 只支持2块硬盘做raid0或者raid1 现在返回去看看MegaCli6
  • NLP(五)命名实体识别(NER)

    本文将会简单介绍自然语言处理 NLP 中的命名实体识别 NER 一 什么是命名实体识别 1 命名实体识别简介 命名实体识别 Named Entity Recognition 简称NER 是信息提取 问答系统 句法分析 机器翻译等应用领域的重
  • 征稿

    我们诚挚地邀请您提交论文参加 ACM MM23 会议上 LGM3A Workshop 主题为 基于大语言模型的多模态研究和应用 LGM3A 2023 the 1st Workshop on Large Generative Models M
  • 可直接使用的unity第三人称自由视角相机脚本

    使用方法 将要控制的角色拖到TargetBody 将相机的焦点拖到CamerPivot 建议CameraPivot是一个放在TargetBody下的子物体 并且位置应该是在TargetBody的头部 注意 此脚本自动忽略 Ignore Ra
  • 准确率、精确率、召回率、F1值学习笔记

    一 TN TP TN FP FN概念 TP与TN都是分对了情况 TP是正类 TN是负类 则推断出 FP是错误的正类 FN是错误的负类 举例 我们需要从一个班级中的人中寻找所有女生 如果把这个任务当成一个分类器的话 那么女生就是我们需要的 而
  • OpenSSL EVP_EncryptInit 函数官方详解

    OpenSSL EVP EncryptInit 函数官方详解 https www openssl org docs manmaster crypto EVP EncryptInit html
  • 新星计划、原力计划新动态,大波的奖牌来袭速来领取

    catalogue 写在前面 原力计划 新星计划 大波奖牌来袭 微软学生开发者峰会 写在最后 写在前面 哈喽 大家好 我是几何心凉 这是一份全新的专栏 得到CSDN王总的授权 来对于我们每周四的绿萝时间 直达CSDN 直播内容进行总结概括
  • 抓住推特群推营销红利,实现低成本精准获客

    随着Twitter在社媒营销中所占流量越来越高 现在做推特引流不会群发 都不敢说自己会玩 使用大量的账号 全天24小时自动发推 抢占搜索热门 进行推特营销时 通过推特群发可以让你的信息快速传播 从而提高你的品牌知名度和推广效果 以下是进行推
  • 单片机论文参考:3、基于单片机的电子万年历设计

    摘要 随着社会 科技的发展 人类得知时间 从观太阳 摆钟到现在电子钟 不断研究 创新 为了在观测时间 能够了解与人类密切相关的信息 比如星期 日期等 电子时钟诞生了 它集时间 日期 星期等功能于一身 具有读取方便 显示直观 功能多样 电路简
  • 写一个查找算法找出数组中相同的元素

    1 import java util ArrayList 2 3 public class Test 4 5 原始数据data 假设data数组中的数据元素已经按照某种顺序排好 6 但是 该数组中的数据元素重复出现 7 我们的目的是查找 解

随机推荐

  • html在线校验器,代码检查错误必备工具-HTML标签检测器

    很多人编写网站代码时 经常会忘记写开始或结束标签 虽然有些标签缺失对网站没有很大影响 但是站在优化角度 一个标签的错误可能会使你的网站在搜索引擎中的评分降低 从而影响关键词排名进度 但是一个网站已经写了很多代码 如何检查错误尤其是标签错误成
  • 以U-NET为例的网络构建代码实现

    写在前面 最近在读U Net论文时 网上看到从零构建网络模型的代码 代码足够间接 而且结构比较完整 因此记录一下学习结果 本文重点在于如何代码的实现 对于U Net论文中的细节未涉略 关于论文的讨论可移步 学习的资源链接在文章末尾 U ne
  • python+pytest+selenium+allure实战

    selenium是一个针对web端项目的模拟鼠标和键盘操作的自动化测试工具 pytest是一个和unittest类似的自动化测试框架 但它比unittest更加方便 并且可以兼容unittest框架 项目结构 common 存放公共方法 比
  • 重力球——重力感应器应用

    首届 Google 暑期大学生博客分享大赛 2010 Andriod 篇 之前在网上看到一个HTC的Windows Mobile手机中的一个应用重力感应器的程序 蛋疼的小球 地址 http v youku com v show id XMT
  • Python字符串的常用方法(3-3)

    目录 一 字符串编码格式 二 字符串的格式化 三 字符串格式化函数 format 四 Python3 6加入的新格式化方案一f strings 五 格式化符号 六 format的使用方法 七 字符串的特殊字符 一 字符串编码格式 1 什么是
  • bootcmd和bootargs环境变量

    从网络启动 setenv bootargs console tty0 console ttymxc0 115200 root dev mmcblk1p2 rootwait rw setenv bootcmd tftp 80800000 zI
  • cuda c语言编程指南,CUDA C编程权威指南

    译者序 推荐序 自序 作者简介 技术审校者简介 前言 致谢 章基于CUDA的异构并行计算1 1 1并行计算1 1 1 1串行编程和并行编程2 1 1 2并行性3 1 1 3计算机架构4 1 2异构计算6 1 2 1异构架构7 1 2 2异构
  • PSIM联合VS--PLL锁相环

    在学习使用PSIM联合VS的过程中 有一项为采样三相电压信号建立软件锁相环练习PI的使用 在查询资料的过程中 网上的百度百科讲PLL作为产生n倍频来使用 这与我之前做电机控制中的PLL概念不太一致 所以产生了疑问 当时的许多知识 现在回头看
  • JetBrains IntelliJ IDEA Ultimate 2022.1.1 Win/macOS 中文

    下载链接 https sbww work 16343 IntelliJ IDEA安装和设置 IntelliJ IDEA 安装要求 硬件需求 至少需要 2 GB RAM 但是推荐使用 4 GB RAM 至少需要 1 5 GB 硬盘空间 1 G
  • 文件文档在线预览转换解决方案和应用

    文章目录 Java Word转PDF文件方案评测 一 kkFileView应用场景一 官网原始部署与应用 二 kkFileView应用场景二 编译 自定义制作docker镜像部署 三 kkfileview预览pdf文件以及关键词高亮和定位
  • Nacos配置管理

    目录 1 Nacos配置管理 1 1 统一配置管理 1 1 1 在nacos中添加配置文件 1 1 2 从微服务拉取配置 1 2 配置热更新 1 2 1 方式一 1 2 2 方式二 1 3 配置共享 1 添加一个环境共享配置 2 在user
  • 财报解读:份额企稳、均价上浮,小米高端化驶入正轨?

    时隔半个月 在雷军那场颇有反响的以 成长 为主题的个人演讲之后 小米发布了今年二季度财报 二季报中亮眼的财务数据 为雷军的演讲提供了一份更加有力的注解 小米经过三年探索 似乎已经找到了高端化的诀窍 因而实现了 成长 但当高端化转型已经成为市
  • 第一章 计算机系统的概述①

    一 操作系统概述 1 操作系统的概念 什么是操作系统 概念 操作系统 Operating System 0s 是指控制和管理整个计算机系统的硬件和软件资源 并合理地组织调度计算机的工作和资源的分配 以提供给用户和其他软件方便的接口和环境 它
  • 失传已久的广工Dr.com路由器最简单最小白的配置方法

    失传已久的广工路由器最简单最小白的配置方法 零 前言 一 准备工作 1 所需物品 2 原理及工具介绍 没兴趣的请直接跳过 二 路由器权限获取 须时两周 三 分析心跳包 1 安装wireshark 2 进行抓包 四 尝试第一次拨号 1 打开W
  • Xcode 之自己编译静态库

    今天介绍下 如何利用Xcode 新建一个静态库 以及如何编译成i386 armv7 armv7s 等平台架构 开发环境 MAC OS X 10 9 4 Xcode 5 0 2 背景知识 库分两种 静态库 a lib 和 动态库 so dll
  • 学员管理系统——面向对象

    文章目录 前言 基本思路 Student py main py StudentManage py 菜单 menu 根据菜单实现程序的大概逻辑 add student 添加学员信息 delete student 删除学员信息 modify s
  • STM32-定时器详解

    目录 前言 一 定时器基本介绍 1 STM32定时器 2 通用定时器功能和特点 3 计数器模式 4 定时器工作原理 a 定时器框图 b 时钟产生器部分 c 时基单元 d 输入捕获通道 e 输出比较通道 PWM 二 定时器中断应用 1 内部时
  • SpringBoot基本操作(四)——SpringBoot使用RedisTemplate整合Redis(有demo)

    SpringBoot2 0笔记 一 SpringBoot基本操作 环境搭建及项目创建 有demo 二 SpringBoot基本操作 使用IDEA打war包发布及测试 三 SpringBoot基本操作 SpringBoot整合SpringDa
  • Visual Studio Community 2019 评估期结束,登录一直失败问题

    今天打开VS2019 发现它试用期过期了需要登录 点击登录 发现一直说浏览器版本太低 需要升级浏览器 真正点击下载Edge浏览器 它又不直接跳转到该浏览器中 反复试了好多次 简直让人崩溃 后来网上搜索到用设备代码流的方式可以解决 https
  • 简图记录-驱动debug之打印总结(printk、dmesg、logcat)

    简图记录总结 在驱动开发过程中 常会用到一些打印做问题定位 无论是提前设计或者调试过程中添加 打印都是一种常用的手段 以下为打印相关问题总结 一 常见驱动打印的添加与查看 1 内核打印printk 概念 printk是内核中根据日志级别向控