数组越界如何产生段错误

数组越界VS段错误

1 栈中数组越界访问

1.1 示例代码
#include<stdio.h>

int main(int argc, char *argv[]){
        printf("0x%x\n", (unsigned int)(-2));
        int a[5] = {0};
        int i;
        printf("%d\n", getpid());
        sleep(100);
        for(i = 0;; i ++){
                printf("0x%lx->%d\n", a + i, a[i]);
        }
        return 0;
}
1.2 测试步骤
(1)编译执行

这里写图片描述

(2)根据PID在proc下面查看进程虚拟地址空间分布

由上图得知,PID=2488,查看/proc/2488/maps文件,内容如下:
这里写图片描述

(3)程序执行结果

这里写图片描述

(4)结论

由/proc/2488/maps文件可以得知:栈stack的范围是:[0x7ffd5c0c1000, 0x7ffd5c0e2000),而由程序执行结果来看,从地址0x7ffd5c0e1ffc处取出一个32位的整数是正常的,但是当从地址0x7ffd5c0e2000处取出一个整数的时候,程序出现段错误。我们可以由文件/proc/2488/maps得到这样的结论:0x7ffd5c0e2000是虚拟地址空间[stack]和[vvar]之间留的空洞,可用于捕获越界访问异常。

2 BSS段中数组越界访问

2.1 示例代码
#include<stdio.h>

int a[5] = {0};

int main(int argc, char *argv[]){
        printf("0x%x\n", (unsigned int)(-2));
        int i;
        printf("%d\n", getpid());
        sleep(30);
        for(i = 0;; i ++){
                printf("0x%lx->%d\n", (unsigned long)(a + i), a[i]);
        }
        return 0;
}
2.2测试步骤
(1)编译执行

这里写图片描述

(2)根据PID在proc下面查看进程虚拟地址空间分布

由上图得知,PID=2645,查看/proc/2645/maps文件,内容如下:
这里写图片描述

(3)执行结果

这里写图片描述

(4)结论

由/proc/2645/maps文件可以得知:BSS段的范围是:[0x 00601000, 0x00602000),而由程序执行结果来看,从地址0x601ffc处取出一个32位的整数是正常的,但是当从地址0x00602000处取出一个整数的时候,程序出现段错误。我们可以由文件/proc/2645/maps得到这样的结论:0x00602000是虚拟地址空间BSS段和堆区之间留的空洞,可用于捕获越界访问异常。

3 堆中数组越界访问

3.1 示例代码
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char *argv[]){
        printf("0x%x\n", (unsigned int)(-2));
        int *a = (int *)malloc(10 * sizeof(int));
        int i;
        printf("%d\n", getpid());
        sleep(30);
        for(i = 0;; i ++){
                printf("0x%lx->%d\n", (unsigned long)(a + i), a[i]);
        }
        return 0;
}
3.2测试步骤
(1)编译执行

这里写图片描述

(2)根据PID在proc下面查看进程虚拟地址空间分布

由上图得知,PID=2690,查看/proc/2690/maps文件,内容如下:
这里写图片描述

(3)执行结果

这里写图片描述

(4)结论

由/proc/2690/maps文件可以得知:堆的范围是:[0x012a5000, 0x012c6000),而由程序执行结果来看,从地址0x12c5ffc处取出一个32位的整数是正常的,但是当从地址0x012c6000处取出一个整数的时候,程序出现段错误。我们可以由文件/proc/2690/maps得到这样的结论:0x012c6000是虚拟地址空间堆区和mmap内存区域之间留的空洞,可用于捕获越界访问异常。

4 结论

  linux操作系统无法准确捕获越界访问,只能通过在虚拟地址空间的各个分离的区域之间设置虚拟地址空洞来捕获越界访问导致的异常。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值