实现步骤:

1、添加$U/_trace到Makefile中的UPROGS变量里;


2、添加声明到user/user.h,添加一个entry到user/usys.pl和一个syscall number到kernel/syscall.h中;


3、添加mask值到proc结构体;

proc结构体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Per-process state
struct proc {
struct spinlock lock;

// p->lock must be held when using these:
enum procstate state; // Process state
struct proc *parent; // Parent process
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
int xstate; // Exit status to be returned to parent's wait
int pid; // Process ID

// these are private to the process, so p->lock need not be held.
uint64 kstack; // Virtual address of kernel stack
uint64 sz; // Size of process memory (bytes)
pagetable_t pagetable; // User page table
struct trapframe *trapframe; // data page for trampoline.S
struct context context; // swtch() here to run process
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
int mask; // 添加mask值
};

4、添加sys_trace()到kernel/sysproc.c

sys_trace实现:

1
2
3
4
5
6
7
8
9
uint64
sys_trace(void)
{
int n;
if (argint(0, &n) < 0) // 判断参数是否获取成功
return -1;
myproc()->mask = n; // 将argv[1]保存到当前进程的mask中
return 0;
}

5、修改kernel/proc.c中的fork函数,添加子进程复制父进程mask的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int
fork(void)
{
/* do something .... */
safestrcpy(np->name, p->name, sizeof(p->name));

// 复制 mask
np->mask = p->mask;

pid = np->pid;

np->state = RUNNABLE;

release(&np->lock);

return pid;
}

6、修改kernel/syscall.c,首先添加声明sys_trace函数,然后添加到syscalls数组中,然后就是修改syscall函数添加trace识别功能

kernel/syscall.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*........*/
extern uint64 sys_uptime(void);
extern uint64 sys_trace(void); // 添加sys_trace声明

static uint64 (*syscalls[])(void) = {
/* ..... */
[SYS_trace] sys_trace, // 添加到syscall数组中
};

// 添加识别名
char* syscalls_name[23] = {"", "fork", "exit", "wait", "pipe", "read", "kill", "exec",
"fstat", "chdir", "dup", "getpid", "sbrk", "sleep", "uptime",
"open", "write", "mknod", "unlink", "link", "mkdir", "close", "trace"};

void
syscall(void)
{
int num;
struct proc *p = myproc();

num = p->trapframe->a7;
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
p->trapframe->a0 = syscalls[num]();
// 添加追踪功能
if (p->mask & (1 << num))
{
printf("%d: syscall %s -> %d\n",p->pid, syscalls_name[num], p->trapframe->a0);
}
} else {
printf("%d %s: unknown sys call %d\n",
p->pid, p->name, num);
p->trapframe->a0 = -1;
}
}