当前位置: 首页 > news >正文

linxu内核的signal fault和arm内核的flault

一、情景引入

我们在分析linux或者安卓系统的coredump文件时,经常碰见SIGSEGV(段错误)、SIGBUS(总线错误)。那么这些错误和arm内核的各种硬件fault有什么关联呢?

二、基本概念

Signal Fault:这是 Linux 系统通过信号机制通知进程发生错误的一种方式。例如,SIGSEGV(段错误)、SIGBUS(总线错误)、SIGILL(非法指令)等信号都属于 Signal Fault。

ARM 内核定义了多种异常类型,用于处理硬件层面的错误情况,常见的 ARM 内核 Fault 包括:

  • Data Abort:在数据访问(读取或写入)出错时触发。
  • Prefetch Abort:指令预取失败时会引发该异常。
  • Undefined Instruction:遇到无法识别的指令时产生。
  • Bus Fault:总线访问失败,比如地址对齐错误或者外设响应超时。

三、关联机制

当 ARM 内核检测到硬件 Fault 时,会触发相应的异常处理流程。Linux 内核中的异常处理程序会捕获这些硬件异常,并将其转换为用户空间的 Signal,具体对应关系如下:

ARM 内核 FaultLinux Signal常见原因
Data AbortSIGSEGV 或 SIGBUS- SIGSEGV:访问未映射的内存地址
- SIGBUS:访问的地址有效,但总线传输失败(如非对齐访问)
Prefetch AbortSIGILL指令地址无效或指令格式错误
Undefined InstructionSIGILL执行了 ARM 架构不支持的指令
Bus FaultSIGBUS总线访问错误,例如地址未对齐、外设故障

SIGSEGV vs SIGBUS

这两个信号都与内存访问错误有关,但具体场景不同:

  • SIGSEGV(段错误):通常是因为访问了未映射的虚拟地址。比如,解引用空指针(*NULL)或者访问越界的数组元素。
  • SIGBUS(总线错误):更多是硬件层面的问题,例如:
    • 非对齐访问(在 ARMv7-M 等架构中,某些指令要求数据地址必须对齐)。
    • 访问物理设备地址时,外设响应错误。

四、映射源码解读

1. ARM 架构的异常处理核心逻辑

  • 文件路径arch/arm/kernel/traps.c
  • 关键函数do_DataAbort()do_PrefetchAbort()do_BusFault()
  • 信号映射示例
    // 处理数据中止异常
    static void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
    {struct siginfo info;...// 根据错误类型设置不同的信号if (user_mode(regs)) {info.si_signo = SIGSEGV;  // 默认发送SIGSEGVinfo.si_code = SEGV_MAPERR;  // 映射错误...force_sig_info(SIGSEGV, &info, current);  // 向当前进程发送信号} else {die("Oops", regs, fault_code);}
    }
    

2. Bus Fault 的具体处理

  • 文件路径arch/arm/mm/fault.c
  • 关键函数do_bad_area()do_translation_fault()
  • 信号映射逻辑
    // 处理无效地址访问
    static int do_bad_area(unsigned long addr, unsigned int fsr,struct pt_regs *regs)
    {if (user_mode(regs)) {// 对用户空间地址,发送SIGSEGVkill_faulted_task(current, addr, fsr, regs, SIGSEGV);return 0;}...
    }
    

3. 非对齐访问的特殊处理

  • 文件路径arch/arm/mm/alignment.c
  • 配置选项:通过CONFIG_ARM_UNALIGNED_ACCESS控制是否允许非对齐访问
  • 信号映射
    // 非对齐访问错误处理
    static void __do_unaligned_access(struct pt_regs *regs, unsigned long addr)
    {if (user_mode(regs)) {// 发送SIGBUS信号force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr, current);return;}...
    }
    

4. ARMv7-M 架构的特殊处理

  • 文件路径arch/arm/mach-cortexm/exception.c
  • 关键函数hard_fault_handler()bus_fault_handler()
  • 信号映射
    // Cortex-M的总线错误处理
    void bus_fault_handler(struct pt_regs *regs)
    {// 通常通过系统调用向用户空间发送SIGBUSsend_sig(SIGBUS, current, 0);...
    }
    

总结

  • 主要映射逻辑arch/arm/kernel/traps.c 和 arch/arm/mm/fault.c
  • 架构差异:ARMv7-M 与 ARMv7-A/R 的处理略有不同,具体取决于内核配置和硬件特性。

http://www.dtcms.com/a/271749.html

相关文章:

  • 【LeetCode100】--- 2.字母异位词分组【复习回顾】
  • 如何发现 Redis 中的 BigKey?
  • 正向代理服务器Squid:功能、架构、部署与应用深度解析
  • 黄瓜苦多于意外,苦瓜苦来自本源——“瓜苦”探源
  • CloudCanal:一款企业级实时数据同步、迁移工具
  • 浪潮CD1000-移动云电脑-RK3528芯片-2+32G-开启ADB ROOT破解教程
  • tomcat源码02 - 理解Tomcat架构设计
  • MyBatis集成Logback日志全攻略
  • 微软云语音识别ASR示例Demo
  • 激活函数与损失函数:神经网络的动力引擎与导航系统
  • defer学习指南
  • 《C++初阶之内存管理》【内存分布 + operator new/delete + 定位new】
  • 启辰智慧预约团队5周年活动掠影,打造一流预约系统
  • 论文精读(一)| 量子计算系统软件研究综述
  • IoT 小程序:如何破解设备互联的碎片化困局?
  • 一条Redis命令是如何执行的?
  • 两种方式清除已经保存的git账号密码
  • 并发编程第一节
  • 【WEB】Polar靶场 Day7 详细笔记
  • 深度学习模型表征提取全解析
  • 【PyTorch】PyTorch中数据准备工作(AI生成)
  • 内置函数(Python)
  • 树莓派免密登录(vs code/cursor)
  • EFK/ELK9.0.3 windows搭建
  • 【DB2】load报错SQL3501W、SQL3109N、SQL2036N
  • 【算法训练营Day10】栈与队列part2
  • SpringBoot mybatis
  • Idea如何解决包冲突
  • P8818 [CSP-S 2022] 策略游戏
  • 【自动驾驶】经典LSS算法解析——深度估计