linux SIGSEGV and SIGBUS

http://blog.youkuaiyun.com/hpwzd/article/details/6434231

涉及共享内存的管理就不能不提到访问共享内存对象。谈到访问共享内存对象就要留神“SIGSEGV和SIGBUS”这两个信号。
系统分配内存页来承载内存映射区,由于内存页大小是固定的,所以存在多余的页空间空闲,比如待映射文件大小为5000 bytes,内存映射区大小也为5000 bytes。而一个内存页大小4096,系统势必要分配两页来承载,这时空闲的有效空间为从5000-8191,如果进程访问这段地址空间也不会发生错误。但是要超出8191,就会收到SIGSEGV信号,导致程序停止。
关于SIGBUS信号的来历,这里也举例说明:若待映射文件大小为5000 bytes,我们在mmap时指定内存映射区size = 15000 > 5000,页承载大小16384,而内核真正的共享区承载体大小只有8192(能包容映射文件大小即可),此时在[0,8191]内访问均没问题,但在[8192, 16383]之间会得到SIGBUS信号;超出16384访问时会触发SIGSEGV信号。

### LinuxSIGSEGV 信号的原因 SIGSEGV 是一种由操作系统发送给程序的信号,表示该程序尝试访问未分配或不允许访问的内存区域。这种行为通常是由于非法引用引起的[^2]。具体来说,以下情况可能导致 SIGSEGV: - **空指针解引用**:当程序试图通过一个指向 NULL 的指针来读取或写入数据时,会触发此信号。 - **越界数组访问**:如果程序超出数组的有效范围进行操作,则可能会引发段错误。 - **堆栈溢出**:函数调用层次过深或者局部变量占用过多空间都可能造成堆栈溢出并最终导致 SIGSEGV。 此外需要注意的是,虽然最常见的原因是上述几种情形之一,但实际上任何违反保护机制的行为都有可能引起此类异常终止;而且值得注意的是,“产生 core 这个动作”的确不仅仅局限于 SIGSEGV 单一类型的事件之中。 ### 处理方法 对于 SIGSEGV 错误的处理主要包括以下几个方面: #### 启用 Core 文件生成 为了能够更好地分析问题所在位置以及上下文环境,在遇到段错误之后应该让系统自动生成核心转储文件 (core dump) 。可以通过设置 ulimit 参数允许创建这些诊断工具所需的大型二进制映像副本: ```bash ulimit -c unlimited ``` 一旦启用了 core 文件支持,并且应用程序崩溃时确实留下了相应的记录,则可以利用专门设计用于解析这类信息的应用软件来进行后续调查工作。例如,可以直接加载到 GDB 当中以便更深入地研究根本原因[^3]。 #### 使用调试器排查问题 GDB 是 GNU 提供的一个强大命令行界面式的源级调试器。它可以帮助开发者找到哪里出了差错。以下是基本的操作流程: 1. 加载可执行文件进入 GDB 环境: ```bash gdb ./your_program ``` 2. 如果已经存在 pre-generated core file ,则可以在启动的同时指定它作为输入参数一起传递进去: ```bash gdb ./your_program /path/to/corefile ``` 3. 执行 `run` 命令使目标重新运行直至再次遭遇致命状况为止; 4. 此刻应当立即显示有关当前线程状态的消息连同其它一些辅助性的元数据详情。此时键入 backtrace 或者其缩写形式 bt 就能获得完整的回溯路径列表,从而快速定位具体的故障部位及其周边关联逻辑结构之间的关系网状图谱[^4]。 另外还可以考虑采用 Valgrind 工具集中的 Memcheck 组件扫描潜在的风险隐患点位,提前预防可能出现的各种 runtime errors 和 memory leaks等问题的发生几率降到最低限度范围内去运作整个项目周期内的质量保障体系架构建设过程里头不可或缺的重要环节组成部分之一部分而已啦! ### 总结 综上所述,理解 SIGSEGV 的成因有助于采取有效的措施防止它的发生。同时掌握必要的技术手段如配置合适的开发环境选项、运用专业的调试技巧等也是解决问题的关键所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值