rk3568 内核态OOM内存泄漏kmemleak使用

1,配置,修改\kernel\arch\arm64\configs\rockchip_linux_defconfig,修改后查看.config.

lark@ubuntu:~/Public/rk356x-linux/rk356x-linux/kernel$ cat .config | grep -i kmemleak

CONFIG_HAVE_DEBUG_KMEMLEAK=y

CONFIG_DEBUG_KMEMLEAK=y

CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000

CONFIG_DEBUG_KMEMLEAK_TEST is not set

CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF is not set

CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y

配置参考:内核内存泄露检测器 --- The Linux Kernel documentation

2,使用前先挂载debug文件系统

mount -t debugfs nodev /sys/kernel/debug/
root@ubuntu2004:/sys/kernel/debug# mount -t debugfs nodev /sys/kernel/debug/

mount: /sys/kernel/debug: nodev already mounted or mount point busy.

挂载失败后卸载重新挂载。

umount -t debugfs nodev /sys/kernel/debug/

清空信息

echo clear > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak

直接扫描查看

echo scan > /sys/kernel/debug/kmemleak

再查看

cat /sys/kernel/debug/kmemleak
root@ubuntu2004:~# echo scan > /sys/kernel/debug/kmemleak

root@ubuntu2004:~# cat /sys/kernel/debug/kmemleak

unreferenced object 0xffffff8013b8ef80 (size 128):

comm "NetworkManager", pid 369, jiffies 4294879794 (age 84.547s)

hex dump (first 32 bytes):

50 4f 4c 4c 00 00 00 00 00 00 01 00 00 00 00 00 POLL............

ac 1a 28 13 80 ff ff ff 00 00 00 00 00 00 00 00 ..(.............

backtrace:

\<00000000607304f6\>\] __kmalloc_track_caller+0x208/0x40c \[\<000000006d5ca9dd\>\] kvasprintf+0x90/0x120 \[\<000000009d2babac\>\] kasprintf+0x54/0x80 \[\<00000000fdf036ee\>\] phy_attached_info_irq+0x5c/0xa0 \[\<00000000031e1948\>\] phylink_bringup_phy+0xd8/0x370 \[\<00000000ff700461\>\] phylink_of_phy_connect+0xfc/0x120 \[\<00000000bbb6560e\>\] stmmac_open+0xa98/0xea0 \[\<00000000b38baf6a\>\] __dev_open+0x10c/0x18c \[\<00000000f07defb8\>\] __dev_change_flags+0x164/0x1c0 \[\<00000000fe90a519\>\] dev_change_flags+0x28/0x64 \[\<00000000b86a7bf8\>\] do_setlink+0x224/0xda4 \[\<000000001d760f93\>\] __rtnl_newlink+0x50c/0x7d0 \[\<0000000022b7a662\>\] rtnl_newlink+0x54/0x80 \[\<0000000000f2f898\>\] rtnetlink_rcv_msg+0x120/0x35c \[\<00000000b3efd0bb\>\] netlink_rcv_skb+0x60/0x12c \[\<00000000bfaee2d8\>\] rtnetlink_rcv+0x1c/0x24

代码里面用到了kasprintf ,在这里看一下使用 kasprintf 时需要注意以下几点:

  1. 分配的内存位于内核空间,不能直接从用户空间访问。
  2. 分配的内存必须通过 kfree 函数来释放,以避免内存泄漏。
  3. 由于 kasprintf 可能会导致睡眠(如果内存紧张时可能需要等待内存分配),因此它不能在中断上下文或持有自旋锁时调用。

函数使用举例

#include <linux/kernel.h>

#include <linux/slab.h>

char *my_kasprintf_function(void)

{

gfp_t gfp = GFP_KERNEL;

char *my_string;

my_string = kasprintf(gfp, "The answer is %d", 42);

if (!my_string)

return NULL; // 分配失败

pr_info("%s\n", my_string); // 在内核日志中打印信息

kfree(my_string); // 释放分配的内存

return my_string;

}

再来看我程序中的代码

char *phy_attached_info_irq(struct phy_device *phydev)

{

char *irq_str;

char irq_num[8];

switch(phydev->irq) {

case PHY_POLL:

irq_str = "POLL";

break;

case PHY_IGNORE_INTERRUPT:

irq_str = "IGNORE";

break;

default:

snprintf(irq_num, sizeof(irq_num), "%d", phydev->irq);

irq_str = irq_num;

break;

}

return kasprintf(GFP_KERNEL, "%s", irq_str);

}

phylink_bringup_phy调用的地方

char *irq_str;

irq_str = phy_attached_info_irq(phy);

分析代码:phylink_bringup_phy代码里面使用完irq_str后没有释放,这样需要释放.

加上kfree(irq_str)再烧写可以看到没有释放的现象。

相关推荐
DuHz13 分钟前
C程序中的数组与指针共生关系
linux·c语言·开发语言·嵌入式硬件·算法
shuair20 分钟前
mysql8支持远程访问 -mysql5.7支持远程访问
linux·mysql
Murphy_lx1 小时前
Linux系统--信号(4--信号捕捉、信号递达)陌生概念篇
linux·运维·服务器
焱焱枫2 小时前
Linux疑难杂症诊断利器:深入解析 fuser 命令
linux·运维·服务器
博语小屋2 小时前
Linux进程信号(壹)_产生信号
linux·运维·服务器
轻松Ai享生活2 小时前
【Linux】VFS 虚拟文件系统 详解
linux
LCG元2 小时前
Linux环境Python生态速建指南:包管理+虚拟隔离+深度调优
linux
大白的编程日记.2 小时前
【Linux学习笔记】线程同步与互斥之生产者消费者模型
linux·笔记·学习
Knight_AL2 小时前
Spring Boot 中使用自定义注解和 AOP 实现微服务日志记录(包含 URL、状态码和耗时信息)
linux·spring boot·微服务
养海绵宝宝的小蜗3 小时前
Linux 例行性工作任务(定时任务)知识点总结
linux·运维·服务器