内核动态打印
Posted Li-Yongjun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核动态打印相关的知识,希望对你有一定的参考价值。
活动地址:CSDN21天学习挑战赛
简介
调试过内核或驱动的小伙伴肯定都用过 printk(),不过 printk() 有个不好的地方,使用打印等级控制其打印,一旦开了某个打印等级,内核和驱动中满足该等级的打印都会打印出来,影响阅读。那有没有什么办法,能够让程序员控制只打印某个文件、某个模块、某个函数的调试信息?有的,那就是内核动态打印。
pr_debug()、dev_dbg()
首先,在内核代码中使用如下函数添加打印信息:
pr_debug()
dev_dbg()
netdev_dbg()
...
net/core/dev.c
static int xmit_one(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq, bool more)
unsigned int len;
int rc;
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
dev_queue_xmit_nit(skb, dev);
len = skb->len;
/* 动态打印 */
netdev_dbg(dev, "[xmit_one] skb->len = %d\\n", skb->len);
trace_net_dev_start_xmit(skb, dev);
rc = netdev_start_xmit(skb, dev, txq, more);
trace_net_dev_xmit(skb, rc, dev, len);
return rc;
CONFIG_DYNAMIC_DEBUG
其次,要打开内核 CONFIG_DYNAMIC_DEBUG 编译选项
# CONFIG_DYNAMIC_DEBUG is not set
CONFIG_DYNAMIC_DEBUG=y
查看
编译、运行后,使用如下命令查看内核中都包含了哪些动态打印语句
root@ATK-IMX6U:~# cat /sys/kernel/debug/dynamic_debug/control | grep net/core/dev.c
net/core/dev.c:5095 [dev]__netdev_adjacent_dev_remove =_ "%s to %s ref_nr-- = %d\\012"
net/core/dev.c:5108 [dev]__netdev_adjacent_dev_remove =_ "dev_put for %s, because link removed from %s to %s\\012"
net/core/dev.c:6013 [dev]rollback_registered_many =_ "unregister_netdevice: device %s/%p never was registered\\012"
net/core/dev.c:5047 [dev]__netdev_adjacent_dev_insert =_ "dev_hold for %s, because of link added from %s to %s\\012"
net/core/dev.c:5227 [dev]__netdev_upper_dev_link =_ "Interlinking %s with %s, non-neighbour\\012"
net/core/dev.c:5237 [dev]__netdev_upper_dev_link =_ "linking %s's upper device %s with %s\\012"
net/core/dev.c:5246 [dev]__netdev_upper_dev_link =_ "linking %s's lower device %s with %s\\012"
net/core/dev.c:2651 [dev]xmit_one =_ "[xmit_one] skb->len = %d\\012"
net/core/dev.c:6105 [dev]netdev_fix_features =_ "Dropping TSO features since no SG feature.\\012"
net/core/dev.c:6111 [dev]netdev_fix_features =_ "Dropping TSO features since no CSUM feature.\\012"
net/core/dev.c:6118 [dev]netdev_fix_features =_ "Dropping TSO6 features since no CSUM feature.\\012"
net/core/dev.c:6128 [dev]netdev_fix_features =_ "Dropping NETIF_F_GSO since no SG feature.\\012"
net/core/dev.c:6139 [dev]netdev_fix_features =_ "Dropping NETIF_F_UFO since no checksum offload features.\\012"
net/core/dev.c:6145 [dev]netdev_fix_features =_ "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\\012"
net/core/dev.c:6179 [dev]__netdev_update_features =_ "Features changed: %pNF -> %pNF\\012"
由于内核原生包含的动态打印语句就很多,所以我们过滤了一下,在 net/core/dev.c 看到了我们添加的打印语句,上面第 9 行。
生效
注意,刚才查看到的动态打印语句默认是不生效的,也就是说,使用 dmesg 是看不到这些打印输出的。要使用如下命令使其生效
root@ATK-IMX6U:~# echo -n "file net/core/dev.c +p" > /sys/kernel/debug/dynamic_debug/control
root@ATK-IMX6U:~# cat /sys/kernel/debug/dynamic_debug/control | grep core/dev.c
net/core/dev.c:5095 [dev]__netdev_adjacent_dev_remove =p "%s to %s ref_nr-- = %d\\012"
net/core/dev.c:5108 [dev]__netdev_adjacent_dev_remove =p "dev_put for %s, because link removed from %s to %s\\012"
net/core/dev.c:6013 [dev]rollback_registered_many =p "unregister_netdevice: device %s/%p never was registered\\012"
net/core/dev.c:5047 [dev]__netdev_adjacent_dev_insert =p "dev_hold for %s, because of link added from %s to %s\\012"
net/core/dev.c:5227 [dev]__netdev_upper_dev_link =p "Interlinking %s with %s, non-neighbour\\012"
net/core/dev.c:5237 [dev]__netdev_upper_dev_link =p "linking %s's upper device %s with %s\\012"
net/core/dev.c:5246 [dev]__netdev_upper_dev_link =p "linking %s's lower device %s with %s\\012"
net/core/dev.c:2650 [dev]xmit_one =p "[1xmit_one] skb->len = %d\\012"
net/core/dev.c:2651 [dev]xmit_one =p "[2xmit_one] skb->len = %d\\012"
net/core/dev.c:6105 [dev]netdev_fix_features =p "Dropping TSO features since no SG feature.\\012"
net/core/dev.c:6111 [dev]netdev_fix_features =p "Dropping TSO features since no CSUM feature.\\012"
net/core/dev.c:6118 [dev]netdev_fix_features =p "Dropping TSO6 features since no CSUM feature.\\012"
net/core/dev.c:6128 [dev]netdev_fix_features =p "Dropping NETIF_F_GSO since no SG feature.\\012"
net/core/dev.c:6139 [dev]netdev_fix_features =p "Dropping NETIF_F_UFO since no checksum offload features.\\012"
net/core/dev.c:6145 [dev]netdev_fix_features =p "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\\012"
net/core/dev.c:6179 [dev]__netdev_update_features =p "Features changed: %pNF -> %pNF\\012"
可以看到从刚才的 =_
变成了 =p
,这样就生效了。
打印
root@ATK-IMX6U:~# dmesg | tail
[ 190.284130] fec 20b4000.ethernet eth0: [xmit_one] skb->len = 85
[ 190.284277] fec 20b4000.ethernet eth0: [xmit_one] skb->len = 105
[ 190.292195] lo: [xmit_one] skb->len = 85
[ 193.254611] fec 20b4000.ethernet eth0: [xmit_one] skb->len = 42
[ 206.169663] fec 20b4000.ethernet eth0: [xmit_one] skb->len = 94
可以看到刚才添加的打印语句 netdev_dbg(dev, "[xmit_one] skb->len = %d\\n", skb->len);
生效了。
以上是关于内核动态打印的主要内容,如果未能解决你的问题,请参考以下文章