[授权发表]Linux内核Section Mismatch详解
来源:互联网 发布:asp管理系统源码 编辑:程序博客网 时间:2024/05/21 09:00
by falcon wuzhangjin@gmail.com of TinyLab.org
2014/01/22
最初发表:泰晓科技 – 聚焦嵌入式 Linux,追本溯源,见微知著!
原文链接:Linux内核Section Mismatch详解
评论说明:为更好地聚合大家的讨论,请到上面原文的评论区回复。
Section Mismatch简介
Section Mismatch是非常严重的Bug,可能会导致无法预测的内存访问问题,建议谨慎对待,如果添加的驱动中有类似Warning,可能需要密切关注并解决掉。
下面就该问题的检测、原因、解决思路以及最新前沿进行分析。
Section Mismatch的检测
CONFIG_DEBUG_SECTION_MISMATCH=y
打开上述选项,内核就会调用modpost
检测类似问题。
Section Mismatch的原因
Linux为了减少不必要的内存消耗,对于一些仅仅在内核初始化时使用的资源(包括函数和变量等),会放在init sections中,这些init sections会在内核初始化完成以后被内核Free掉。除此之外,考虑到不同模块或者子系统的差异,它们的代码和数据也会放在各自的Section中,交叉的引用也可能出现潜在的问题。
如果一个Section引用了另外一个Section中的变量,就会出现Section Mismatch警告。如果是一个运行时函数引用了一个Init Section段中的函数,那么问题就出现了。
当Linux内核启动完成后,Init Section占用的内存已经被Free掉,如果这部分内存被其他的设备申请,写进了不可预知的内容,那么系统就会存在不可预知的风险,也许有些时候会很幸运,这部分内存从来都没有被其他设备引用,所以,即使编译时看到了Warning,系统也没有崩溃,但是炸弹放在枕头边,很危险,早点搬走为好。
Section Mismatch的解决
有几种情况:
- 如果运行时函数引用了Init Section中的函数或者变量
如果该运行时函数是必须要在运行时用到的,不能放到Init Section中,那么就把Init Section中的函数的__init*
标记去掉,否则给前者加上相应的Init声明。
相关的init标记请参考:include/linux/init.h
- 如果不同的Section之间存在交叉引用,这个交叉引用是安全的,则用
__ref
标记让Section Mismatch Detector(modpost)忽略相关检查
比如在cpu hotplug中,__cpuinit
不会放在Init section中,在运行时访问是安全的,如果有一个外部函数(无__cpuinit
标记)访问了用__cpuinit
标记的函数,这个时候就存在交叉引用。因为这种访问是安全的,所以可以让内核忽略对它的检测,用__ref
标记该函数即可。
Section Mismatch的近况
在最新的ARM内核中,引入了一个智能检测,该检测是针对Free掉的内存被运行时函数访问的情况,前面的分析提到类似的情况会导致无法预测的风险,而该智能检测则会明确地报告出具体的问题。
该检测的原理是把所有Init Section的内存区域在内核初始化时把这些内存区域初始化为0xe7fddef0 (an undefined instruction (ARM) or a branch to an undefined instruction (Thumb)),如果运行时函数非法访问到了这些区域,会触发一个undef instruction的异常并打印相应的回调,从而辅助开发人员更快地解决相关问题。
当然,这并不意味着我们不需要解决编译时的Warning,把问题Delay到运行时解决是更耗费精力的,应该在编码或者编译等早期开发过程中就解决掉,这样会提高开发效率,这个思路对其他的问题同样适用。
这部分的代码请参考:arch/arm/mm/init.c: poison_init_mem()
- [授权发表]Linux内核Section Mismatch详解
- [授权发表]用 kGDB 调试 Linux 内核
- [授权发表]内核探索:Linux BogoMips 探秘
- [授权发表]Linux 段错误详解
- [授权发表]源码分析:动态分析 Linux 内核函数调用关系
- [授权发表]为可执行文件“减肥”
- [授权发表]如何快速定位 Linux Panic 出错的代码行
- [授权发表]为什么计算机的学生要学习 Linux 开源技术
- [授权发表]基于 Docker 快速构建 Linux 0.11 实验环境
- [授权发表]把 VIM 打造成源代码编辑器
- [授权发表]GCC 编译背后的奥秘
- [授权发表]程序执行的那一刹那
- [授权发表]动态符号链接的细节
- [授权发表]缓冲区溢出与注入分析
- [授权发表]进程的内存映像
- [授权发表]进程和进程的基本操作
- [授权发表]代码测试、调试与优化小结
- [授权发表]开源书籍:《Shell编程范例》
- 杭电ACM1251——统计难题~简单字典树的应用
- POST表单数据无法获取到
- Android如何快速入门
- 杭电1201 18岁生日
- Foundation框架
- [授权发表]Linux内核Section Mismatch详解
- Google Protocol Buffer 的使用和原理
- retain和release倒底怎么玩?
- CheatMaker教学进阶之一 - 基地址与指针
- MySql的源代码文件夹
- java中的匿名内部类总结
- [授权发表]用 kGDB 调试 Linux 内核
- php中文乱码问题
- 【剑指Offer学习】【面试题2 : 实现Singleton 模式——七种实现方式】