00_创建系统调用的基本步骤
01_System call tracing(追踪)
1.实验目标
实现一个可以追踪任意系统调用的系统调用,当设置了追踪源码mask之后,对应编号的系统调用在触发时都会被追踪,并打印出如下的信息
2.实验步骤
(1)添加用户态程序的UPROGS字段
xv6已经实现了一个文件trace.c
,这是一个用户态程序,所以只需要在makefile
里面加上将_trace
加入UPROGS
字段就行。
(2)添加掩码用于进程追踪
在表示每个进程的结构体proc(kernel/proc.h)
中加入一个表示用于进程追踪的掩码
(3)实现sys_trace的逻辑
sys_trace
的逻辑是在sysproc.c
的文件中实现的(sysproc.c
是负责处理与系统调用相关的过程(process)管理)。这个实现设计到用户态向内核态中传递参数,需要使用诸如argraw,argint, argaddr,argstr
等函数,从trapframe
(用于保存当处理器进入异常处理或中断处理程序时的上下文信息的一种数据结构)中将用户态下传递的参数读取到内核态。所以在内核态下的系统调用函数,都是没有参数的,因为它们的参数都是从用户态下读进来的。
-
argraw
上述提到的函数都是调用了
argraw
来解析参数,argraw
的逻辑是从对应的trapframe
中返回a0-a7
寄存器,这几个寄存器是用来存放函数参数的。// 以64位无符号整数返回寄存器a0-a7中的值 // 当n大于5的时候,函数错误,陷入panic static uint64 argraw(int n) { struct proc *p = myproc(); switch (n) { case 0: return p->trapframe->a0; case 1: return p->trapframe->a1; case 2: return p->trapframe->a2; case 3: return p->trapframe->a3; case 4: return p->trapframe->a4; case 5: return p->trapframe->a5; } panic("argraw"); return -1; }
-
sys_trace
sys_trace
的实现直接将用户态下传进来的追踪掩码存入当前进程的TraceMask(之前刚加入的变量属性)即可。参考sys_exit
:
可以写出:
(4)实现追踪当前进程子进程的功能
想要实现追踪当前进程子进程的功能,需要在进程调用fork
时,子进程应该将TraceMask
一并复制过去,
做法也很简单,直接在fork函数中,将p->TraceMask
赋值给 np->TraceMask
就行
(5)满足实验要求的追踪形式
-
建立映射表
在syscall.h中建立从系统调用号映射到名称的映射表
- 在syscall中给出具体打印内容
Comments | NOTHING