• 内核动态打印


    活动地址:CSDN21天学习挑战赛

    简介

    调试过内核或驱动的小伙伴肯定都用过 printk(),不过 printk() 有个不好的地方,使用打印等级控制其打印,一旦开了某个打印等级,内核和驱动中满足该等级的打印都会打印出来,影响阅读。那有没有什么办法,能够让程序员控制只打印某个文件、某个模块、某个函数的调试信息?有的,那就是内核动态打印。

    pr_debug()、dev_dbg()

    首先,在内核代码中使用如下函数添加打印信息:

    pr_debug()
    dev_dbg()
    netdev_dbg()
    ...
    
    • 1
    • 2
    • 3
    • 4

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    CONFIG_DYNAMIC_DEBUG

    其次,要打开内核 CONFIG_DYNAMIC_DEBUG 编译选项

    # CONFIG_DYNAMIC_DEBUG is not set
    CONFIG_DYNAMIC_DEBUG=y
    
    • 1
    • 2

    查看

    编译、运行后,使用如下命令查看内核中都包含了哪些动态打印语句

    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"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    由于内核原生包含的动态打印语句就很多,所以我们过滤了一下,在 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"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看到从刚才的 =_ 变成了 =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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以看到刚才添加的打印语句 netdev_dbg(dev, "[xmit_one] skb->len = %d\n", skb->len); 生效了。

  • 相关阅读:
    【已解决】VSCode LaTeX支持minted
    解决el-tree子节点过多导致渲染缓慢问题
    使用jieba测试分词并且增加自定义字典
    Linux aarch64交叉编译之glm数学库
    SAP ABAP——数据类型(三)【TYPE-POOL和INCLUDE嵌套定义类型】
    Guacamole 配置开启 Radius 身份认证方式
    视频推拉流EasyDSS平台直播通道重连无法转推的原因排查与解决
    java毕业设计琳琅天上超市管理系统mybatis+源码+调试部署+系统+数据库+lw
    C语言学习笔记
    java+python离退休人员工资管理系统
  • 原文地址:https://blog.csdn.net/lyndon_li/article/details/126276835