Lab4 Traps
RISC-V Assembly
主要是回答一下关于汇编的问题,难度不大
Backtrace
实现一个函数,能够打印出栈上函数调用链,以帮助出错时的调试。
原理也比较简单:利用栈结构的性质(返回地址和上一个栈帧指针在栈中存放位置是固定的),由当前栈帧指针开始,不断向上得到栈中返回地址,直到到达栈的底部。
1 |
|
Alarm
要求实现一个机制,在调用了
sigalarm(interval, handler)
后,该进程每消耗interval
个时间片,就要调用一次handler
函数。
思路
实现的核心是:编写sigalarm
、sigreturn
两个系统调用和修改usertrap
中处理时钟中断的部分代码。
下图是核心函数之间的调用关系,也是该部分的重点和难点,因为涉及内核空间和用户空间的频繁切换。
重点需要理解的有两点:
usertrap
位于内核空间,而handler function
位于用户空间,3
号箭头应该如何发生?由于
usertrap
是在处理异常的一个环节中,最后还是会返回到用户空间中,如果不做处理返回的是源代码发生中断的位置,而该位置是由sepc
寄存器保存的,在usertrap
中sepc
寄存器中的值被保存在了p->trapframe->epc
中,所以只要将p->trapframe->epc
的值设置成handler function
的地址即可sigreturn
系统调用是handler function
调用的,如何使其返回时回到user code
原先被时钟中断的那部分代码,即5
号箭头如何发生?这一部分其实和第一点类似,只要设置
p->trapframe->epc
就可以使其返回到原先被中断处,但是还需要考虑如何恢复源代码的上下文,就需要恢复所有的寄存器。所以需要在usertrap
中保存p->trapframe
中的所有值,然后在sys_sigreturn
处恢复
实现
两个系统调用
1 |
|
usertrap
中针对时钟中断的的实现
1 |
|
问题
1、usertrap
中只保存了handler函数处理完的返回地址,并没有保存一整套寄存器,导致回到user code
之后,上下文改变了,所以发生了异常
2、p->savedtrapframe
在初始化时没有分配内存,导致发生了内存store
时的缺页异常。
3、p->savedtrapframe
没有释放