debugfs:Linux 内核调试的利器

目录

  • 一、什么是 debugfs?
  • 二、debugfs 的配置和启用方式
    • 2.1 内核配置选项
    • 2.2 挂载 debugfs
    • 2.3 Android 系统中的 debugfs
  • 三、debugfs 的典型应用场景
    • 3.1 调试驱动开发
    • 3.2 内核子系统调试
    • 3.3 性能分析
  • 四、常见 debugfs 子目录与功能示例
    • 4.1 /sys/kernel/debug/tracing - 内核跟踪核心目录
    • 4.2 /sys/kernel/debug/gpio - GPIO 状态调试
    • 4.3 /sys/kernel/debug/regulator - 电源调节器状态
    • 4.4 /sys/kernel/debug/dma_buf - DMA buffer 分析
    • 4.5 /sys/kernel/debug/<自定义驱动名>/
  • 五、调试案例:自定义驱动中使用 debugfs
  • 六、debugfs 的工作原理和核心机制
  • 七、核心 API 总览
  • 八、线上环境下的注意事项与安全性问题
    • 8.1 信息泄露风险
    • 8.2 系统稳定性风险
    • 8.3 Android 安全限制节
  • 九、补充:debugfs 与 procfs、sysfs 的区别


一、什么是 debugfs?

debugfs 是 Linux 内核提供的一个专用文件系统,主要用于内核与用户空间之间的调试信息交换。它为内核开发人员或者驱动开发者提供了一种无需修改内核代码即可获取内部状态的方式。

相比 /proc 和 /sys,debugfs 更偏向临时调试用途,适合暴露实验性、不稳定或仅用于开发阶段的接口。

特点

动态创建、无需重新编译内核。
文件操作接口简单,可通过 shell 脚本或 C 语言轻松操作。
开发者常用于调试驱动、查看内部状态、动态注入参数等。


二、debugfs 的配置和启用方式

2.1 内核配置选项

要使用 debugfs,首先需要在编译内核时启用支持:

CONFIG_DEBUG_FS=y

如果你使用的是 Android 或嵌入式系统,也可在 menuconfig 中启用:

Kernel hacking  --->  
[*] Debug Filesystem

此选项默认对主线内核是开启的,但某些发行版或定制系统可能关闭以减小体积或提高安全性。

2.2 挂载 debugfs

一般系统启动时不会自动挂载 debugfs,你可以手动挂载:

sudo mount -t debugfs none /sys/kernel/debug

也可以在启动脚本中加入自动挂载逻辑:

if ! mountpoint -q /sys/kernel/debug; then  mount -t debugfs none /sys/kernel/debug
fi

验证:

 ls /sys/kernel/debug/

输出类似如下则表示挂载成功:

bdi/  clk/  gpio/  tracing/  suspend_stats  ...

2.3 Android 系统中的 debugfs

Android 默认处于安全模式,大多数生产环境中是关闭的。可以通过如下方式在开发版系统中开启:

adb shell
mount -t debugfs debugfs /sys/kernel/debug

部分 Android 内核会禁用 CONFIG_DEBUG_FS,需要通过修改 kernel defconfig 启用并重新编译。

三、debugfs 的典型应用场景

debugfs 通常用于以下几个方面:

3.1 调试驱动开发

我们可以将调试信息、参数、状态变量通过 debugfs 暴露出来,便于动态查看或调整,而无需反复修改内核代码、重启内核。例如:

读取设备寄存器
控制调试开关(如 loglevel)
查看缓存、状态统计信息等

3.2 内核子系统调试

很多内核子系统默认就通过 debugfs 暴露接口,例如:

tracing(ftrace)
gpio 状态查看与操作
regulator 状态与调节
DMA buf debug 信息
audio 子系统的 debug log(如 asoc)

3.3 性能分析

结合 ftrace(内核函数跟踪器)可以做函数调用路径分析、系统延迟检测、实时调试。


四、常见 debugfs 子目录与功能示例

4.1 /sys/kernel/debug/tracing - 内核跟踪核心目录

这是 ftrace 的主目录,可以分析函数调用、调度、延迟等。常见文件:

available_tracers:可用的跟踪器类型
current_tracer:当前启用的跟踪器
trace:跟踪结果输出
set_ftrace_filter:设置要跟踪的函数

示例:

# 开启函数跟踪
echo function > /sys/kernel/debug/tracing/current_tracer
# 查看 trace 日志
cat /sys/kernel/debug/tracing/trace

4.2 /sys/kernel/debug/gpio - GPIO 状态调试

查看系统中所有 GPIO 控制器和当前引脚状态:

cat /sys/kernel/debug/gpio

输出类似:

gpiochip0: GPIOs 0-31, parent: platform/10012000.gpio, gpio-controller 
gpio-4   (sysfs               ) out hi    
gpio-17  (wifi_power         ) out lo    

4.3 /sys/kernel/debug/regulator - 电源调节器状态

可查看/调试 regulator 驱动注册的电压、状态等:

cat /sys/kernel/debug/regulator/ */status
cat /sys/kernel/debug/regulator/ */microvolts

4.4 /sys/kernel/debug/dma_buf - DMA buffer 分析

可用于分析图形子系统中共享内存的引用情况:

cat /sys/kernel/debug/dma_buf/bufinfo

4.5 /sys/kernel/debug/<自定义驱动名>/

我们可以调用 debugfs_create_* 系列 API 在这里创建自己的调试目录和接口,支持暴露:

整数、布尔变量
文件接口(read/write)
二进制 blob(例如 buffer dump)


五、调试案例:自定义驱动中使用 debugfs

一个简单的例子:假如我们正在开发一个字符设备驱动,需要调试内部状态:

#include <linux/debugfs.h>
static struct dentry *debug_dir;
static u32 debug_val = 0;
static int __init mydrv_init(void)
{debug_dir = debugfs_create_dir("mydrv", NULL);if (!debug_dir)return -ENOMEM;debugfs_create_u32("debug_val", 0644, debug_dir, &debug_val);return 0;
}
static void __exit mydrv_exit(void)
{debugfs_remove_recursive(debug_dir);
}

加载驱动后可直接查看或设置:

cat /sys/kernel/debug/mydrv/debug_val
echo 42 > /sys/kernel/debug/mydrv/debug_val

这比 printk + 重编译 + 重启流程更高效,尤其适合频繁调试场景。


六、debugfs 的工作原理和核心机制

debugfs 实际上是一个虚拟文件系统(Virtual File System, VFS),类似于 /proc/sys,其底层由内核代码负责维护和注册。

它的本质是
内核将特定结构体变量映射为文件或目录,通过 file_operations 让用户空间可以读写这些内核变量或结构体。

关键实现机制

  • debugfs_create_*() 系列 API 用于创建虚拟文件
  • 每个文件背后对应一个 file_operations,封装了 read/write 行为
  • 这些文件操作最终在 debugfs 挂载点下暴露给用户空间

例如,debugfs_create_u32("val", 0644, parent, &var) 就等价于暴露了一个变量 var 到文件系统中,可以直接读写。模块注册结构图如下:
在这里插入图片描述


七、核心 API 总览

基本语法格式:

API名称功能
debugfs_create_dir(name, parent)创建子目录
debugfs create file(name, mode, parent, data, fops)创建具备操作函数的文件
debugfs_create_u32(name, mode, parent, ptr)绑定变量为 u32 文件
debugfs_create bool(name, mode, parent, ptr)创建布尔值控制项
debugfs_remove(entry)删除单个debugfs项
debugfs_remove_recursive(entry)递归删除整个目录树

示例:绑定一个只读的布尔变量

static bool debug_flag = true;
debugfs_create_bool("enable_debug", 0444, parent_dir, &debug_flag);

用户空间读取:

cat /sys/kernel/debug/mydrv/enable_debug

虽然 debugfs 极大地方便了开发与调试,但在生产环境下要慎用或禁用,主要原因包括:

八、线上环境下的注意事项与安全性问题

8.1 信息泄露风险

  • debugfs 会暴露大量内核内部信息,黑客或恶意程序可借此探测系统结构。
  • 某些接口甚至允许直接写入数据,可能对系统稳定性产生影响。

8.2 系统稳定性风险

  • 由于很多 debugfs 文件由开发者编写,若实现不严谨可能导致 panic。
  • 示例:越界访问、没有加锁保护、引用了已释放的结构体等。

8.3 Android 安全限制节

  • Android 生产版默认关闭 debugfs
  • SELinux 和 seccomp 等机制会阻止其挂载

推荐的安全策略:

  • 线上系统关闭 CONFIG_DEBUG_FS,从内核构建阶段禁止。
  • 或者通过配置挂载权限为只读,并结合 SELinux 限制访问。
  • 对自定义 debugfs 文件做好访问控制,严格限制 read/write 权限。

九、补充:debugfs 与 procfs、sysfs 的区别

特性debugfsprocfssysfs
主要用途调试/开发进程信息内核对象模型
是否稳定否(可变)
是否推荐线上启用
是否支持驱动自定义接口支持支持但复杂支持但需 class/device

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lua 作为嵌入式设备的配置语言

从lua的脚本中获取数据 lua中栈的索引 3 | -1 2 | -2 1 | -3 可以在lua的解释器中加入自己自定的一些功能,其实没啥必要,就是为了可以练习下lua

棋牌室台球室快速接入美团团购接口

北极星平台从2024年12月份开始慢慢关闭&#xff0c;现在很多开发者反馈北极星token已经不能刷新了&#xff0c;全部迁移到美团团购综合平台。 申请这个平台要求很高 1、保证金费用要15万起步 2、平台必须是二级等保和安全产品 &#xff0c;一个二级等保费用10万起步 所以很多…

开源轻量级地图解决方案leaflet

Leaflet 地图&#xff1a;开源轻量级地图解决方案 Leaflet 是一个开源的 JavaScript 库&#xff0c;用于在网页中嵌入交互式地图。它以轻量级、灵活性和易用性著称&#xff0c;适用于需要快速集成地图功能的项目。以下是关于 Leaflet 的详细介绍和使用指南。 1. Leaflet 的核心…

一个批量文件Dos2Unix程序(Microsoft Store,开源)1.1.0 编码检测和预览

之前的版本是个意思意思&#xff0c;验证商店发布的&#xff08;其实是我以前自己用的工具&#xff09;&#xff0c;这次把格式检查和转换都做上了&#xff0c;功能应该差不多了&#xff0c;还有一些需要小改进的地方。 因为还没什么用户嘛&#xff0c;还是保持全功能免费试用。…

特征提取:如何从不同模态中获取有效信息?

在多模态学习中&#xff0c;不同模态&#xff08;文本、图像、语音、视频、传感器数据等&#xff09;所携带的信息丰富且互补。但不同模态的数据结构、表示空间、时空分布截然不同&#xff0c;因此&#xff0c;如何对各模态进行高效、有效的特征提取&#xff0c;是整个多模态学…

Go语言爬虫系列教程 实战项目JS逆向实现CSDN文章导出教程

爬虫实战&#xff1a;JS逆向实现CSDN文章导出教程 在这篇教程中&#xff0c;我将带领大家实现一个实用的爬虫项目&#xff1a;导出你在CSDN上发布的所有文章。通过分析CSDN的API请求签名机制&#xff0c;我们将绕过平台限制&#xff0c;获取自己的所有文章内容&#xff0c;并以…

交叉熵损失函数,KL散度, Focal loss

交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09; 交叉熵损失函数&#xff0c;涉及两个概念&#xff0c;一个是损失函数&#xff0c;一个是交叉熵。 首先&#xff0c;对于损失函数。在机器学习中&#xff0c;损失函数就是用来衡量我们模型的预测结果与真实结果之间…

149.WEB渗透测试-MySQL基础(四)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;148.WEB渗透测试-MySQL基础&#xff08;三&#xff09; 非关系型数据库&#xff1a; &a…

c/c++中程序内存区域的划分

c/c程序内存分配的几个区域&#xff1a; 1.栈区&#xff1a;在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结束时这些存储单元自动被释放&#xff0c;栈内存分配运算内置于处理器的指令集中&#xff0c;效率很高但是分配的内存容量有…

构建稳定的金字塔模式生态:从自然法则到系统工程

在自然界中&#xff0c;金字塔结构广泛存在于生态系统之中&#xff0c;表现为营养级能量金字塔、生物量金字塔和数量金字塔等形式。这种结构不仅形象地描述了生态能量流转的规律&#xff0c;也体现出生态系统中“稳定性”与“层级性”的天然法则。在现代软件架构、企业组织、平…

Vue 3.0双向数据绑定实现原理

Vue3 的数据双向绑定是通过响应式系统来实现的。相比于 Vue2&#xff0c;Vue3 在响应式系统上做了很多改进&#xff0c;主要使用了 Proxy 对象来替代原来的 Object.defineProperty。本文将介绍 Vue3 数据双向绑定的主要特点和实现方式。 1. 响应式系统 1.1. Proxy对象 Vue3 …

TIP-2021《SRGAT: Single Image Super-Resolution With Graph Attention Network》

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

大语言模型与多模态模型比较

一、核心差异&#xff1a;输入数据类型与模态融合 输入数据类型 LLM&#xff1a;仅处理文本数据&#xff0c;例如文本分类、机器翻译、问答等任务&#xff0c;通过大规模语料库学习语言规律。 LMM&#xff1a;支持文本、图像、音频、视频等多种模态输入&#xff0c;例如根据图…

Apache HttpClient 5 用法-Java调用http服务

Apache HttpClient 5 核心用法详解 Apache HttpClient 5 是 Apache 基金会推出的新一代 HTTP 客户端库&#xff0c;相比 4.x 版本在性能、模块化和易用性上有显著提升。以下是其核心用法及最佳实践&#xff1a; 一、添加依赖 Maven 项目&#xff1a; <dependency><…

基于 Spark 的流量统计

一、引言 在互联网行业&#xff0c;流量统计是分析网站或应用用户行为、评估业务表现、优化资源分配以及制定营销策略的关键环节。借助 Apache Spark 强大的分布式数据处理能力&#xff0c;我们可以高效地对大规模的流量数据进行统计分析&#xff0c;获取有价值的洞察。本文将…

Python模块化编程进阶指南:从基础到工程化实践

一、模块化编程核心原理与最佳实践 1.1 模块化设计原则 根据企业级项目实践&#xff0c;模块化开发应遵循以下核心原则&#xff1a; ​​单一职责原则​​&#xff1a;每个模块只承担一个功能域的任务&#xff08;如用户认证模块独立于日志模块&#xff09;​​接口隔离原则…

锐捷交换机STP环路日志信息解读

因公司网络组建使用锐捷全系列交换机&#xff0c;近期设备巡检时发现部分日志提示信息&#xff0c; 接入交换机NBS3100-24GT4SFP-V2&#xff0c;设备频繁打出STP Blocking的日志信息。 误以为是环路导致&#xff0c;故进行实验测试&#xff0c;来验证环路情况下会如何报日志。…

使用Python调用DeepSeek的示例

使用Python调用DeepSeek API的示例代码,包括API密钥的获取、基本请求的发送以及响应处理。请确保你已经注册了DeepSeek账号并获取了API密钥。 文章目录 前言一、获取API密钥二、python示例代码三、代码说明四、注意事项五、扩展功能总结前言 提示:这里可以添加本文要记录的大…

mysql的not exists走索引吗

在MySQL中&#xff0c;​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下是关键点总结&#xff1a; ​索引的作用​&#xff1a; 当子查询的关联字段&#xff08;例如B.a_id&#xff09;存在索引&#xff08;如普通B-tree索引&#xff09;时&…

Python线性回归:从理论到实践的完整指南

Python线性回归&#xff1a;从理论到实践的完整指南 线性回归是数据科学和机器学习中最基础且最重要的算法之一。本文将深入探讨如何使用Python实现线性回归&#xff0c;从理论基础到实际应用&#xff0c;帮助读者全面理解这一重要的统计学和机器学习方法。 什么是线性回归&a…