0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用动态输出打印内核的DEBUG信息

嵌入式与Linux那些事 来源:嵌入式与Linux那些事 2023-01-06 10:46 次阅读

简介

printk()是很多嵌入式开发者喜欢用的调试手段之一,但是,使用printk()每次都要重新编译内核,很不方便。使用动态输出在不需要重新编译内核的情况下,方便的打印出内核的debug信息

要开启动态输出,内核需要添加CONFIG_DYNAMIC_DEBUG。开启宏之后,pr_debug(),dev_dbg() ,print_hex_dump_debug(),print_hex_dump_bytes()`所有信息都可以被动态打印出来。

动态输出支持的特性

动态输出在debugfs文件系统中对应的是control文件节点。control文件节点记录了系统中所有使用动态输出技术的文件名路径,输出语句所在的行号、模块名和将要输出的语句等。

你可以通过以下命令查看目前所有调试状态的行为配置:

cat/sys/kernel/debug/dynamic_debug/control

你也可以应用标准的Unix文本过滤命令来过滤这些数据, 例如:

grep-irdma/sys/kernel/debug/dynamic_debug/control|wc-l

在第三列显示了调试状态位的激活标志。如果无额外行为被激话, 为 "=_"。因此你可以通过下面的命令查看任何不是默认标志的状态位:

awk'$3!="=_"'/dynamic_debug/control

命令行使用方法

在语法层面上,一个命令由一系列的规格匹配组成,最后由一个标记来改变这规格。

command::=match-spec*flags-spec

match-spec常用来选择一个已知的dprintk()调用点的子集来套用flags-spec。把他们当做彼此之间的每对做隐式查询。注意,一个空的match_specs列表是有可能的,但不是非常有用,因为它不会匹配任何调用点的调试子句。

一个匹配规范由一个关键字组成,关键字控制被比较的调用点的属性和要比较的值。可能关键字是:

match-spec::='func'string|
'file'string|
'module'string|
'format'string|
'line'line-range
line-range::=lineno|
'-'lineno|
lineno'-'|
lineno'-'lineno

注意:line-range不能包含空格,例如,“1-30”是有效的范围,但“1 - 30”就是无效的

每个关键字的含义如下:

func:给定的字符串会和每个调用点的函数名比较。例如:func svc_tcp_accept

file:给定的字符串会和每个调用点的源文件的全路径名或者相对名比较。例如:file svcsock.c, file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c

module:给定的字符串会和每个调用点的模块名进行比较。模块名是和在ls mod 里看到的字符串一样。例如,module sunrpc

format:给定的字符串会在动态调试格式字符串里查找。注意这字符串不需要匹配这个格式。空格和其他特殊字符能够用八进制字符语法来转义,例如空字符是�40。作为选择,这个字符串可以附上双引号(")或者是单引号(‘)。例如:

formatsvcrdma://NFS/RDMA服务器的dprintks
formatreadahead//一些在预加载缓存里的dprintks
formatnfsd:�40SETATTR//一个使用空格来匹配格式的方式
format"nfsd:SETATTR"//一个整齐的方法来用空格匹配格式
format'nfsd:SETATTR'//同样是一个用空格来匹配格式的方法和

line:给定的行号或者是行号范围会和每个dprintk()调用点的行号进行比较。例如:

line1603//准确定位到1603行
line1600-1605//1600行到1605行之间的6行
line-1605//从第一行到1605行之间的1605行
line1600-//从1600行到结尾的全部行

标记规范包含了一个由一个或多个标记字符跟随的变化操作。这变化操作如下所示:

-//移除给定的标记

+//加入给定的标记

=//设置标记到给定的标记上

f//包含已打印消息的函数名

l//包含已在打印消息的行号

m//包含已打印消息的模块名

p//产生一个printk()消息到显示系统启动日志

t//包含了不在中断上下文中产生的消息里的线程ID

传递启动参数给内核

在调试系统启动是时,像USB核心初始化等,这些代码在系统进入shell前已经初始化完毕,因此无法及时打开动态输出语句。这时可以在内核启动时传递参数给内核,在系统初始化时就打开它们。

例如,在内核命令行中添加 usbnet.dyndbg=+plft ,就可以在启动时打开 usbnet的动态输出。

在内核启动后,通过 dmesg | grep "usbnet" 即可看到输出的调试信息。

举例

打开文件svcsock.c 1603行动态输出语句

echo-n'filesvcsock.cline1603+p'>/sys/kernel/debug/dynamic_debug/control

打开文件svcsock.c所有动态输出语句

echo-n'filesvcsock.c+p'>/sys/kernel/debug/dynamic_debug/control

打开NFS服务模块所有动态输出语句

echo-n'modulenfsd+p'>/sys/kernel/debug/dynamic_debug/control

打开函数svc_process()的所有动态输出语句

echo-n'funcsvc_process+p'>/sys/kernel/debug/dynamic_debug/control

关闭函数svc_process()的所有动态输出语句

echo-n'funcsvc_process-p'>/sys/kernel/debug/dynamic_debug/control

打开NFS调用的所有以READ开始的信息.

echo-n'format"nfsd:READ"+p'>/sys/kernel/debug/dynamic_debug/control

查看输出的信息可以使用 dmesg | grep XXX 。也可以使用 tail -f /var/log/dmesg来实时监控dmesg的日志输出。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5056

    文章

    18953

    浏览量

    301633
  • 内核
    +关注

    关注

    3

    文章

    1357

    浏览量

    40179
  • 字符串
    +关注

    关注

    1

    文章

    568

    浏览量

    20461
  • DEBUG
    +关注

    关注

    3

    文章

    89

    浏览量

    19843

原文标题:使用动态输出打印内核的DEBUG信息

文章出处:【微信号:嵌入式与Linux那些事,微信公众号:嵌入式与Linux那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux内核学习笔记:动态输出调试

    上篇说到printk调试,但printk是全局的,只能设置输出等级。而动态输出可以动态选择打开某个内核子系统的
    发表于 06-01 15:16 481次阅读
    Linux<b class='flag-5'>内核</b>学习笔记:<b class='flag-5'>动态</b><b class='flag-5'>输出</b>调试

    STM32WB55开发(4)----配置串口打印Debug调试信息

    在STM32WB55系列微控制器上进行开发时,实时监控应用程序的运行情况和调试潜在问题是至关重要的。使用串口(USART/UART)进行Debug信息打印是一种简便、高效的方法。下面是如何在STM32WB55上配置串口来
    的头像 发表于 12-01 15:48 1145次阅读
    STM32WB55开发(4)----配置串口<b class='flag-5'>打印</b><b class='flag-5'>Debug</b>调试<b class='flag-5'>信息</b>

    [求助]winCE板子进桌面后就不打印debug信息

    我的mini2440+winCE,在板子启动时,屏幕出现欢迎界面时串口能打印debug信息,但进入桌面后就不打印了,有的正在打印的函数名,只
    发表于 03-06 14:11

    内核调试解惑!

    解惑!我在使用飞思卡尔的单片机(M0+内核的)用J-link做一个串口调试,就是在程序里调用printf函数然后在keil的Debug(printf)Viewer或者是Debug Uart#里
    发表于 01-23 11:10

    AM335x linuxBSP 编出的内核没有打印启动信息

    使用TI提供的linux-3.1.0-psp04.06.00.03.sdk编译的内核只是将pr_err信息打印出来了,请问如何设置可以讲内核启动信息
    发表于 05-15 07:06

    am335x调试内核时怎么设置输出打印信息

    请问怎么设置输出打印信息啊?用printk后还要修改其他宏吗?请知道的朋友告诉我,写下步骤。谢谢。
    发表于 06-21 03:12

    多任务环境下串口输出debug信息的方法是什么?

    debug信息交错到一起的现象。于是我又添加了另一种输出的方式:为debug输出额外创建一个进程专用于
    发表于 07-20 08:03

    如何利用串口输出printf的打印信息

    PC机上,printf输出到显示设备,在嵌入式linux系统,一般利用printf输出调试信息,需要重定向到串口。以AT91RM9200为例,简要说明如何利用串口输出printf的
    发表于 11-04 07:10

    分享一下Linux内核日志与信息打印

    嵌入式软件调试技术专题(3):Linux内核日志与信息打印 6年嵌入式开发经...
    发表于 12-23 07:36

    串口DEBUG只有打印信息的功能吗

    使用串口DEBUG,只是看到boot的一些信息,无法登录?这是因为这个debug功能只是打印信息?额外问一下,想在target 端 编译开发,要安装GCC等,但是不可以使用连到包管理服
    发表于 01-11 06:25

    PRINT指定输出串口1的打印信息,如果想输出其他串口0的信息,怎么修改?

    PRINT指定输出串口1的打印信息,如果想输出其他串口0的信息,怎么修改!
    发表于 08-09 07:32

    嵌入式log打印格式输出技巧

    嵌入式log打印格式输出技巧Log 信息格式条件编译可变参数宏C标准中一些预定义的宏格式输出16进制数组Log 信息格式参考目前主流嵌入式、
    发表于 10-20 21:06 5次下载
    嵌入式log<b class='flag-5'>打印</b>格式<b class='flag-5'>输出</b>技巧

    Linux内核动态输出调试

    pr_debug()/dev_dbg()函数来输出信息,这些就使用了动态输出。 需要打开的内核
    的头像 发表于 09-27 15:45 498次阅读
    Linux<b class='flag-5'>内核</b><b class='flag-5'>动态</b><b class='flag-5'>输出</b>调试

    Linux内核基础:动态输出使用

    动态输出使用 打开svcsock.c文件中所有的动态输出语句 # echo 'file svcsock.c +p' > /sys/ kernel /
    的头像 发表于 09-27 15:51 458次阅读
    Linux<b class='flag-5'>内核</b>基础:<b class='flag-5'>动态</b><b class='flag-5'>输出</b>使用

    内核调试工具printkprintk的输出格式

    很多内核开发者喜欢的调试工具是printk,在Linux内核中,使用printk()函数来打印信息,它与C库的printf()函数类似。 printk()与printf()的一个重要
    的头像 发表于 09-27 16:09 962次阅读