ошибки fork () в OS161 - PullRequest
       104

ошибки fork () в OS161

0 голосов
/ 18 марта 2020

У меня есть тестер, который вызывает fork в al oop, чтобы убедиться, что fork выживает. Но после создания только 5 дочерних процессов мы получаем эту ошибку:

Fatal user mode trap 2 (TLB miss on load, epc 0x400464, vaddr 0x400464)

Вот код для sys_fork:

 pid_t sys_fork(struct trapframe tf,int retval){

    //disable interrupts (not sure if i need this line)
    //int s=splhigh();

    //the pid of the current thread (each process only has one thread so this pid belongs to both curthread and curprocess)
    parent_pid=curthread->t_pid;

    //a global variable for the newly generated pid (for the child process)
    child3_pid=pid_generator(parent_pid);

    //if the pid is 0 that means we are out of the PIDs
    if(child3_pid==0){

        //return the error (too many PIDs)
        *retval=-1;
        return EAGAIN;
    }

int result;

    //create a new process
    struct process* child_process=create_process("Child Process",child3_pid);

    //if the new process is NULL retrun the error
    if(child_process==NULL){
        *retval=-1;
        return ENOMEM;  
    }


//create a new address space for the child (which is a copy of the parent's trapframe)
struct trapframe* parent_tf=kmalloc(sizeof(struct trapframe));
if(parent_tf==NULL){
    *retval=-1;
    return ENOMEM;
}
memcpy(parent_tf,tf,sizeof(struct trapframe));

//create a new thread for the child process and pass it to thread fork
struct thread* child_thread;
    result=thread_fork("Child Process",parent_tf,0,&md_forkentry,&child_thread);

    //if thread fork fails
    if (result) {

        //free the new address space
        kfree(parent_tf);

        //destroy the new process
        process_destroy(child_process);

        //remove the process from the proces table
        process_pid_table[child3_pid]=NULL;
        *retval=-1;
        return result; 
    }


    //if thread fork does not fail, we can setup the parent PID and child PID to the new process
    child_process->pid=child3_pid;
    child_process->ppid=parent_pid;
    *retval=child_process->pid;
    //splx(s);
    return 0;
}

Это код для md_forkentry:

void md_forkentry(void *tf,unsigned long n)

{
    (void) n;
    /*
     * This function is provided as a reminder. You need to write
     * both it and the code that calls it.
     *
     * Thus, you can trash it and do things another way if you prefer.
     */
        /*
         * before returning to user mode, we need to copy the modified trapframe 
         * from kernel heap to stack, then use its address as parameter to call 
         * mips_usermode,
         */
int s;
    s = splhigh();
         //the new address space 
         struct trapframe trap;

    //copy the address space from the parent address space
    memcpy(&trap,tf,sizeof(struct trapframe));


        /*
         * We need to set our return value in the copied trapframe to 0 since 
         * we are the child which is done by modifying the v0 register. Also
         * increment program counter to stop reentry of the same system call         
         */

    trap.tf_v0 = 0;
     trap.tf_epc += 4; 
    trap.tf_a3 = 0;    

    //switch to user mode 


    splx(s);
    mips_usermode(&trap);

        //kprintf("fork_entry child %l: returning to user mode\n", parent_addr_space);




}

По сути, мы должны иметь возможность создать больше дочерних процессов, чем 5. Поскольку ошибка кажется ошибкой пользовательского режима (в зависимости от адреса), я понятия не имел, где происходит сбой даже при использовании GDB (может ' дайте мне, где это не удается на основе адреса). Кто-нибудь знает, что может быть не так?

...