2020 mit6.s081 os Lab: xv6 traps

本文档详细介绍了RISC-V架构下的内核调试技巧,包括寄存器使用、栈帧分析、回溯函数以及系统调用的实现。实验中涉及了printf函数的实现、backtrace功能的添加以及自定义的alarm系统调用。实验者通过修改内核代码实现了在特定时间间隔后调用用户态函数的功能,并利用GDB进行调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

友情链接:全部实验哟


实验链接

https://pdos.csail.mit.edu/6.S081/2020/labs/pgtbl.html


实验

RISC-V assembly

  1. a0-a7,13保存在a2里

  2. 函数f和g直接被内联优化了,即printf的第2个参数直接是12(f(8)+1的结果).

    在这里插入图片描述

  3. 0x640

    在这里插入图片描述

  4. ra保存的是函数调用后返回的地址,由下图可以看出为0x38

    在这里插入图片描述

  5. He110 World(本人的机器是小端的,所以是这个输入,如果是大端的,输出则不一样)

    unsigned int i = 0x00646c72;
    printf("H%x Wo%s", 57616, &i);
    
  6. y的输出结果为0,保存的是a2寄存器中的值。

    printf("x=%d y=%d", 3);
    

Backtrace

该题的主要目的是打印当前进程的调用链,为实现该函数,我们首先需要了解栈的分布情况,如下图所示:

  1. stack地址从高到低进行增长;
  2. sp: 指向栈的最底端;
  3. fp: 当前栈帧的顶端;
  4. return address是地址是fp-8
  5. prev frame fp保存地址是fp-16

在这里插入图片描述

按照实验提示进行代码更改:

  1. kernel/defs.h,添加头文件。

    // printf.c
    void            printf(char*, ...);
    void            panic(char*) __attribute__((noreturn));
    void            printfinit(void);
    // begin++++
    void            backtrace(void);
    // end------
    
  2. kernel/syspro.c,在函数sys_sleep中添加调用

    uint64
    sys_sleep(void)
    {
         
         
      int n;
      uint ticks0;
       // begin+++++
       backtrace();
       // end-------
    
      if(argint(0, &n) < 0)
        return -1;
      acquire(&tickslock);
      ticks0 = ticks;
      while(ticks - ticks0 < n){
         
         
        if(myproc()->killed){
         
         
          release(&tickslock);
          return -1;
        }
        sleep(&ticks, &tickslock
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值