-
Added syscall (
trace
) definitions (in the same format as the other syscalls given) to:syscall.h
syscall.c
usys.pl
-
Added syscall (
trace
) definition with 2 arguments touser.h
-
Added arrays for easy access to syscall names (
char* sysnames
) and no of arguments(int sysargs
) in thesyscall
function to be able to trace properly -
Added
p->trac_stat
tostruct proc
in order to detect if thetrace
syscall was called and changedprocalloc
andfreeproc
to initialize and decomission, respectively,p->trac_stat
to 0. -
Copied value of parent's
trac_stat
to child infork
function inproc.c
-
Added the code for the
trace
syscall to sysproc:uint64 sys_trace(void){ int x; argint(0,&x); // printf("Syscall number: %d \n",x); myproc()->trac_stat = x; return 0; }
If trace is called, it changes
p->trac_stat
to the argument passed in trace (if it is a valid argument). -
Added the code to print the syscall (according to the given instructions in the assignment) in the
syscall
function as that is what handles calling of all syscalls. Updated part of the function:if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { // prints the function before executing (to take care of printing exit, as it doesn't return), and also taking care of printing trace as p->trac_stat hasn't been changed yet if((num==SYS_trace && (argraw(0) & 1<<num)) || (p->trac_stat & 1<<num)){ printf("%d: syscall %s (",p->pid,sysnames[num]); if(sysargs[num]==0){ printf(")"); } else{ for(int i=0;i<sysargs[num];i++){ printf("%d ",argraw(i)); } printf("\b)"); } if(num==SYS_exit){ printf("\n"); } } //executes the syscall function p->trapframe->a0 = syscalls[num](); //printing return value if((num==SYS_trace && (argraw(0) & 1<<num)) || (p->trac_stat & 1<<num)){ printf(" -> %d\n",p->trapframe->a0); }
-
Added
strace.c
user program to user.h and made corresponding change in the makefilestrace.h
#include "../kernel/types.h" #include "user.h" int main(int argc, char** argv){ if(argc<=2){ printf("strace: Too few arguments\n"); return -1; } int mask = atoi(argv[1]); // printf("%d\n",mask); //if mask is negative if(argv[1][0]=='-'){ printf("strace: Invalid bitmask\n"); return -1; } trace(mask); exec(argv[2], (argv + 2)); return 0; }
change in makefile
$U/_strace\
- Added syscalls (
sigalarm
&sigreturn
) definitions (in the same format as the other syscalls given) to:syscall.h
syscall.c
usys.pl
- Added syscall (
sigalarm
) with 2 arguments and syscall (sigreturn
) with no arguments' definitions touser.h
- Added the following values to
struct proc
:int nticks
: stores the number of ticks the process has gone through since calling the alarm function / alarm handler (it gets reset after calling the handler)int alarm_lock
: ensures that nticks isn't incremented while the alarm handler is running (may cause an infinite recursion)int ticklim
: stores the first argument of the sigalarm syscall, the number of ticks after which the handler must be calleduint64 fn
: stores the pointer to the alarm handler - must be uint64 since we will be adding it to the program counter of the current process (to run it immediately after it gets allocated to some processor), and the pc only takes uint64 values.struct trapframe *trapframecpy
: stores a copy of the registers of the process before adding the alarm handler to the pc in order to be able to restore it when sigreturn is called.
- Made corresponding changes to the
procalloc
andfreeproc
functions, in order to initialize and decomission the above variables. - Added the
sigalarm
function tosysproc
:uint64 sys_sigalarm(void){ // printf("Alarm handler called\n"); struct proc* p = myproc(); int n; uint64 fn; argint(0, &n); argaddr(1,&fn); p->ticklim = n; p->nticks = 0; p->fn = fn; return 0; }
- Added the
sigreturn
function tosysproc
:Note: we need to make a change in theuint64 sys_sigreturn(void){ struct proc* p = myproc(); *(p->trapframe) = *(p->trapframecpy); // kfree((void*)p->trapframecpy); p->alarm_lock = 0; return 0; }
syscall
function too, as sigreturn edits trapframe->a0 to store the return value, which we must restore top->trapframecpy->a0
before freeing it:if(num==SYS_sigreturn){ p->trapframe->a0 = p->trapframecpy->a0; kfree((void*)p->trapframecpy); }
- Added the following code under
if(which_dev==2)
(a timer interrupt was raised) underusertrap
(user functions are the only ones calling sigalarm and sigreturn) in order to take care of incrementingp->nticks
and adding the handler function to the pc if required:if(which_dev == 2){ if(p->ticklim>0 && !p->alarm_lock){ p->nticks++; // p->ticks_prev = ticks; if(p->nticks==p->ticklim){ // printf("Executing function\n"); // printf("%d\n",p->nticks); p->alarm_lock = 1; p->nticks = 0; p->trapframecpy = (struct trapframe *)kalloc(); *(p->trapframecpy) = *(p->trapframe); p->trapframe->epc = p->fn; // printf("Function finished executing\n"); } } // printf("Yielded\n"); yield(); }