Linux内核中dev_info、dev_dbg、dev_err及动态调试是怎样的

发布时间:2021-09-27 16:49:21 作者:柒染
来源:亿速云 阅读:285

Linux内核中dev_info、dev_dbg、dev_err及动态调试是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

目前在kernel驱动代码中,都不再建议直接使用printk直接添加打印信息,而是使用dev_info,dev_dbg,dev_err之类的函数代替,虽然这些dev_xxx函数的本质还是使用printk打印的,但是相比起printk:

下面简述下这几个dev_xxx函数的基本使用规则,以及动态调试使用方式。

动态调试使用方法

mkdir /mnt/dbg mount -t debugfs none /mnt/dbg

例子

echo -n "file ca_dsc_core.c +p" > /mnt/dbg/dynamic_debug/control 则打印ca_dsc_core.c所有的dev_dbg()信息 echo -n "func ca_dsc_read +p" > /mnt/dbg/dynamic_debug/control 则打印ca_dsc_read()函数所有dev_dbg()信息

动态打印调试的基本原理

当编译选项CONFIG_DYNAMIC_DEBUG打开的时候,在编译阶段,kernel会把所有使用dev_dbg()的信息记录在一个table中,这些信息我们可以从/mnt/dbg/dynamic_debug/control解析出来:

# cat /mnt/dbg/dynamic_debug/control ... ... ... ... drivers/alidrivers/modules/alidsc/ca_dsc_core.c:800 [alidsc]ca_dsc_probe_dt =_ "get dev-index error12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:789 [alidsc]ca_dsc_probe_dt =_ "get clk error12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:292 [alidsc]ca_dsc_read =p "read: session#%d read returned %d bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:234 [alidsc]ca_dsc_read =p "read: session#%d read request: %zd bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:435 [alidsc]ca_dsc_vm_fault =_ "dsc_vm_fault: buffer#%d release %d bytes for session#%d12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:112 [alidsc]ca_dsc_open =_ "dsc_se: failed register se12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:755 [alidsc]ca_dsc_splice_write =_ "splice_write: session#%d dsc_from_pipe %d bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:729 [alidsc]ca_dsc_splice_write =_ "splice_write: session#%d count %zd bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:619 [alidsc]ca_dsc_splice_read =_ "splice_read: session#%d ret %zd bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:532 [alidsc]ca_dsc_splice_read =_ "splice_read: session#%d request %zd bytes12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:871 [alidsc]ca_dsc_probe =_ "Get DSC handler error!12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:820 [alidsc]ca_dsc_probe =_ "Failed to parse DT12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:923 [alidsc]ca_dsc_remove =_ "get clk error12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:396 [alidsc]ca_dsc_write =_ "write: session#%d ret %zd12" drivers/alidrivers/modules/alidsc/ca_dsc_core.c:325 [alidsc]ca_dsc_write =_ "write: session#%d count %zd12" ... ... ... ... net/ipv4/ping.c:965 [ping]ping_rcv =_ "no socket, dropping12" net/ipv4/ping.c:960 [ping]ping_rcv =_ "rcv on socket %p12" net/ipv4/ping.c:953 [ping]ping_rcv =_ "ping_rcv(skb=%p,id=%04x,seq=%04x)12" net/ipv4/ping.c:932 [ping]ping_queue_rcv_skb =_ "ping_queue_rcv_skb -> failed12" net/ipv4/ping.c:929 [ping]ping_queue_rcv_skb =_ "ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)12" net/ipv4/ping.c:921 [ping]ping_recvmsg =_ "ping_recvmsg -> %d12" net/ipv4/ping.c:840 [ping]ping_recvmsg =_ "ping_recvmsg(sk=%p,sk->num=%u)12" net/ipv4/ping.c:693 [ping]ping_v4_sendmsg =_ "ping_v4_sendmsg(sk=%p,sk->num=%u)12" net/ipv4/ping.c:197 [ping]ping_lookup =_ "found: %p: num=%d, daddr=%pI4, dif=%d12" net/ipv4/ping.c:189 [ping]ping_lookup =_ "iterate12" net/ipv4/ping.c:176 [ping]ping_lookup =_ "try to find: num = %d, daddr = %pI4, dif = %d12" net/ipv4/ping.c:505 [ping]ping_err =_ "err on socket %p12" net/ipv4/ping.c:502 [ping]ping_err =_ "no socket, dropping12" net/ipv4/ping.c:498 [ping]ping_err =_ "ping_err(proto=0x%x,type=%d,code=%d,id=%04x,seq=%04x)12" net/ipv4/ping.c:304 [ping]ping_check_bind_addr =_ "ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)12" net/ipv4/ping.c:445 [ping]ping_bind =_ "ping_v4_bind -> %d12" net/ipv4/ping.c:423 [ping]ping_bind =_ "after bind(): num = %d, dif = %d12" net/ipv4/ping.c:286 [ping]ping_close =_ "isk->refcnt = %d12" net/ipv4/ping.c:285 [ping]ping_close =_ "ping_close(sk=%p,sk->num=%u)12" net/ipv4/ping.c:153 [ping]ping_unhash =_ "ping_unhash(isk=%p,isk->num=%u)12" net/ipv4/ping.c:146 [ping]ping_hash =_ "ping_hash(sk->port=%u)12" net/ipv4/ping.c:67 [ping]ping_hashfn =_ "hash(%d) = %d12" net/ipv4/ping.c:130 [ping]ping_get_port =_ "was not hashed12" net/ipv4/ping.c:127 [ping]ping_get_port =_ "found port/ident = %d12"

以其中一条为例子:

drivers/alidrivers/modules/alidsc/ca_dsc_core.c:800 [alidsc]ca_dsc_probe_dt =_ "get dev-index error12" 则不会打印 drivers/alidrivers/modules/alidsc/ca_dsc_core.c:800 [alidsc]ca_dsc_probe_dt =p "get dev-index error12" 则会打印

所以在应用层,用户就可以通过使用echo来控制dynamic_debug/control文件,进而控制是否打印某个dev_dbg()信息!

代码分析

从代码角度,也很容易看出dev_dbg()的设计:

include/linux/device.h include/linux/dynamic_debug.h lib/dynamic_debug.c
//使能CONFIG_DYNAMIC_DEBUG后则根据control信息动态打印 #if defined(CONFIG_DYNAMIC_DEBUG)  #define dev_dbg(dev, format, ...)         do {              dynamic_dev_dbg(dev, format, ##__VA_ARGS__);   } while (0) //使能DEBUG,则打印整个kernel的dev_dbg信息 #elif defined(DEBUG)  #define dev_dbg(dev, format, arg...)     dev_printk(KERN_DEBUG, dev, format, ##arg) //都不使能,dev_dbg不打印任何东西 #else  #define dev_dbg(dev, format, arg...)      ({           if (0)           dev_printk(KERN_DEBUG, dev, format, ##arg);    0;         }) #endif

下面的dynamic_dev_dbg()实现显然可以看出,打印是根据descriptor的标志位_DPRINTK_FLAGS_PRINT进行打印的,而标志位是可以通过dbgfs进行控制的。

#define dynamic_dev_dbg(dev, fmt, ...)     do {          DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);    if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT))    __dynamic_dev_dbg(&descriptor, dev, fmt,        ##__VA_ARGS__);   } while (0)

看完上述内容,你们掌握Linux内核中dev_info、dev_dbg、dev_err及动态调试是怎样的的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

推荐阅读:
  1. Smali动态调试方法
  2. iOS中怎么实现动态调试

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

linux

上一篇:如何在Linux系统中设置RAID 10确保高性能和容错的磁盘输入/输出

下一篇:Linux手工入侵排查思路是怎样的

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》