[6.s081]Lab Traps

Overview

This lab refreshes our knowledge(if there are any) on RISCV ISA and the flow of traps. Three different traps suppot by xv6: 1. Exception: caused by illegal instruction like dividing by zero. 2. System Calls: kernel level and user level 3. Interrupts: hardwares send signals trying to get attention

Backtrace

Using the pointer that points to the last stackframe's fp to get the address of stack frame one by one. Be careful when to stop the loop. The stack frame is allocated on a page.

void
backtrace(void)
{
    printf("backtrace:\n");
    struct proc *p = myproc();
    uint64 fp=r_fp();

    while(1) {
        // use the fp - 8 to get the return address of the last fp
        uint64 ret_addr = *((uint64*)(fp-8));
        fp = *((uint64*)(fp - 16));
        if(PGROUNDUP(fp) != p->kstack+PGSIZE) {
            break;
        }
        printf("%p\n", ret_addr);
    }
}

Alarm

Defined a customized handler for time interrupts. Set the timer information by a system call sigalarm() for the handler to know when to get into the customized handler. The tests will call sigreturn() to restore the stack information of the user program.

// sysproc.c
uint64
sys_sigalarm(void)
{
    struct proc* p = myproc();
    int ticks;
    uint64 handler;

    if(argint(0, &ticks) < 0) {
        return -1;
    }

    if(argaddr(1, &handler) < 0) {
        return -1;
    }   

    p->alarmticks = ticks;
    p->handler=handler;
    return 0;
}

uint64
sys_sigreturn(void)
{
    struct proc *p = myproc();
    p->ishandling = 0;
    memmove(p->trapframe, p->alarmframe, PGSIZE);
    return 0;
}

// trap.c
void
usertrap(void)
{
  // some code...
  } else if((which_dev = devintr()) != 0){
    // ok
        if(which_dev == 2 && p->alarmticks != 0) {
            p->curticks += 1;
            if(p->curticks % p->alarmticks == 0 && p->ishandling == 0) {
                memmove(p->alarmframe, p->trapframe, PGSIZE);
                p->trapframe->epc = p->handler;
                p->ishandling = 1;
            }
        }
  }
  // some code...
}