操作系统访问内存异常问题排查
在写内核代码的时候定义了一个结构体,在往结构体里属性赋值时访问内存异常,直接jump到未知地址。
代码如下:
在执行stack->function=function时报错。
排查过程:
考虑是否是代码写的有问题,先在本机编写相同代码用gcc编译运行来测试,结果没有任何问题。
考虑是否是stack->function这个内存地址问题,可能是这个内存地址不能读写导致,通过gdb编译查看stack->function的内存地址为
初看好像没有问题,是在内核地址的高1G范围内,但是当时忽略了这个地址的页表是否有问题。
后来查看当执行到这个地方时的页表内容为:
可以看到这个0xc0103ff0虚拟地址在页表里是没有映射项的。
然后分析stack->function的内存地址是malloc_page分配的,然后给malloc_page分配的起始又加上了4096来定位到该页的高地址。代码如下:
这里就有个问题,就是C语言里的 地址加 和 数字加 的区别。具体可以查相关博客,关键词:C语言指针加1。这里是指针加一,所以并不是期望的地址值加上4096,而是加上了2^14次方,导致地址值超过了分配的地址最大值,页表里找不到映射项,所以访问地址异常。
代码改成注释的那段就可以解决这个问题,让pcb->thread_stack的地址落在了页表的映射项上。