ReturnInfinity / BareMetal-OS-legacy

BareMetal is a 64-bit OS for x86-64 based computers. The OS is written entirely in Assembly while applications can be written in Assembly, C/C++, and Rust.
1.75k stars 302 forks source link

Newlib - exit() crash #50

Closed IanSeyler closed 9 years ago

IanSeyler commented 11 years ago

Calls to exit() cause a GP fault.

IanSeyler commented 11 years ago

Is something in crt0.c required for this? Should syscalls.c exit() have a fflush(stdout)?

vilhelmgray commented 9 years ago

The standard C exit function provided by newlib calls the _exit function defined in the syscalls.c file. Currently, the BareMetal syscalls.c _exit function is defined as follows:

// exit -- Exit a program without cleaning up files
int _exit(int val)
{
        exit(val);
        return (-1);
}

The call to the standard C exit function creates an infinite recursion which I believe leads to the crash.

This _exit function should be reimplemented to use an appropriate BareMetal system call in order to "exit the program without cleaning up files." Furthermore, the _exit function prototype's return type is void so the function should not return a value.

ohnx commented 9 years ago

One possible (but probably horrible) solution would be to call the command line in exit()...

vilhelmgray commented 9 years ago

Actually, since the description of the _exit function explicitly states that the program should not clean up files, simply calling the command line in the _exit function would provide the behavior we expect in a monotasking operating system like BareMetal: the running program exits immediately to the command line, thus allowing the next program to run.

Note that this would be a minimal implementation that should be improved in the future: most users expect operating systems to clean up files for them on a standard C _Exit call; however, the minimal implementation will at least solve the crash and make the function usable.

Refer to section 7.20.4.4 of the C99 standard for more information on the standard C requirements of the _Exit function (of which the newlib _exit function is essentially an alias).

vilhelmgray commented 9 years ago

I'm not sure if this will compile, but it should be close to the general solution for a minimal implementation (note the void return type):

// exit -- Exit a program without cleaning up files
void _exit(int val)
{
        asm volatile ("call os_command_line");
}

The os_command_line routine is in the cli.asm file, but since it wasn't aligned in the kernel_start routine in the kernel64.asm file like the other system calls, I'm not sure if that inline assembly I added will work -- I'm not familiar enough with the code.

benaryorg commented 9 years ago

Please have a look at #83 for some possible solutions.