-
Notifications
You must be signed in to change notification settings - Fork 116
Description
I am trying to create a window manager user program in which a list of programs are passed to the window manager and the window manager forks and execs each of them in their own windows. However, there seems to be a bug in the exec call.
Initially, running this fork and exec program fails:
#include "library/syscalls.h"
#include "library/string.h"
int main()
{
int pid = process_fork();
if (pid == 0) {
printf("hello world, I am the child %d.\n", process_self());
const char *args[] = { "snake.exe" };
process_exec("snake.exe", args, 1);
} else {
printf("hello world, I am the parent %d.\n", process_self());
struct process_info info;
process_wait(&info, -1);
process_reap(info.pid);
}
return 0;
}It produces the following exception:

After doing some debugging, I have found that something goes wrong in the process_switch function. At the end of the sys_process_exec, it calls process_yield, which calls process_switch(PROCESS_STATE_READY). Here is the code for process_switch:
static void process_switch(int newstate)
{
interrupt_block();
if(current) {
if(current->state != PROCESS_STATE_CRADLE) {
asm("pushl %ebp");
asm("pushl %edi");
asm("pushl %esi");
asm("pushl %edx");
asm("pushl %ecx");
asm("pushl %ebx");
asm("pushl %eax");
asm("movl %%esp, %0":"=r"(current->kstack_ptr));
}
interrupt_stack_pointer = (void *) INTERRUPT_STACK_TOP;
current->state = newstate;
if(newstate == PROCESS_STATE_READY) {
list_push_tail(&ready_list, ¤t->node);
}
if(newstate == PROCESS_STATE_GRAVE) {
list_push_tail(&grave_list, ¤t->node);
}
}
current = 0;
while(1) {
current = (struct process *) list_pop_head(&ready_list);
if(current)
break;
interrupt_unblock();
interrupt_wait();
interrupt_block();
}
current->state = PROCESS_STATE_RUNNING;
interrupt_stack_pointer = current->kstack_top;
asm("movl %0, %%cr3"::"r"(current->pagetable));
asm("movl %0, %%esp"::"r"(current->kstack_ptr));
asm("popl %eax");
asm("popl %ebx");
asm("popl %ecx");
asm("popl %edx");
asm("popl %esi");
asm("popl %edi");
asm("popl %ebp");
interrupt_unblock();
}I have found that the program works by adding a dumby for loop before the while loop as a delay:
for (int i = 0; i < 100000; ++i)
{
continue;
}
while(1) {While this obviously is not a solution, I think it might indicate that there is some kind of race condition going on.