xv6 COW Lab中碰到的bug

xv6 COW Lab中碰到的bug

  1. 内核地址0x80090000地址作为(struct run*)结构体即空闲内存结构体时下一个(->next)指向了一个非法地址0x7fXXXXXX(因为<0x80000000内核代码地址地址,这下面的地址和操作系统无关)。

    为什么会这样呢?

    因为数组写越界了。这里为了统计每个页表的引用数,声明了一个数组static uint8 pgrefcount[(PHYSTOP - KERNBASE) >> PGSHIFT] = {0}; 注意这里PHYSTOP - KERNBASE。Here is the problem. 更新数组时没有减去KERNBASE。本来应该是pgrefcount[(pa- KERNBASE) >> PGSHIFT] += (uint8)n;,我写成了pgrefcount[pa>> PGSHIFT] += (uint8)n;,这个数组大概在0x8008XXXX的位置,xv6初始化时kfreerange()会调用kfree()把kernel最后的地址和PHYSTOP中间的内存串成空闲内存链,同时kfree()会逐个更新每个页对应pgrefcount。因为没有减去KERNBASE,所以数组写越界了,后面的pgrefcount元素直接把0x80090000数据给覆盖掉了。

    怎么找到的原因?

    问题出在kalloc()返回了一个非法地址0x7fXXXXXX,这很奇怪,如果没有空闲内存应该返回0才对。他的上一个空闲内存是0x80090000(即((struct run *)0x80090000)->next指向0x7fXXXXXX),而且不管我怎么改代码,永远是0x80090000出事,因此我在kfree()中插入

 if ((uint64)(((struct run *)0x80090000)->next) > 0x7f000000 && (uint64)(((struct run *)0x80090000)->next) < 0x80000000){
    		  printf("(uint64)(((struct run *)0x80090000)->next): %p ", (uint64)(((struct run *)0x80090000)->next));
		  panic("dead.\n");
}

发现kfreerange()串链子的时候会把0x80090000的下个空闲内存指向0x7fXXXXXX,由此猜测数组越界,done。(中间过程比这复杂亿点点)

  1. threetest()处理Store/AMO page fault异常时报错:fault_vaddr:0x0000000000000000, page: 0x0000000000000000, pte: 0x0000000021fd0c5b, sepc: 0x000000008000204e pid: 6 意思就是stval为0。

为什么会这样呢?
并发原因。threetest()一共三个进程,如果同时触发Store/AMO page fault异常,就会造成这个问题(中间具体是什么原因,我确实也不明白,还是要学习一个)。

怎么解决?请看VCR

  } else if (r_scause() == 15){
    // Store/AMO page fault

    if(killed(p))
      exit(-1);

    uint64 fault_vaddr = r_stval();
    intr_on();
    storepagefault(fault_vaddr);
  } else if((which_dev = devintr()) != 0){

intr_on();放在uint64 fault_vaddr = r_stval();后面,因为r_stval()会把stval中的值取出来,之后管你并发把stval变成什么。如果放在uint64 fault_vaddr = r_stval();前面,就会触发上面的bug。done

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值