Compare commits

..

6 Commits

Author SHA1 Message Date
f22689fcf5
libc: Add stubs for fflush() and ungetc()
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 10:48:02 +02:00
6bfc7483bc
libc: Add a definition for FILENAME_MAX 2023-06-19 10:47:43 +02:00
acfad51ac0
libc: Add freopen() 2023-06-19 10:46:08 +02:00
7efc3a6ea1
kernel: Show stack traces on page faults + crash the process instead of the whole system on GPFs 2023-06-19 10:45:08 +02:00
0b553cadc0
libluna: Do not fault if vstring_format() is called with buf=nullptr
Instead, just discard the output and return the number of bytes formatted, as mandated by the C standard.
2023-06-19 10:44:33 +02:00
ae01a31104
kernel: Make sure the stack is 16-byte aligned on program startup
This is required by the System V ABI and fixes some movaps-related GPFs in ndisasm.
2023-06-19 10:41:32 +02:00
6 changed files with 80 additions and 12 deletions

View File

@ -80,6 +80,8 @@ void decode_page_fault_error_code(u64 code)
decode_page_fault_error_code(regs->error);
CPU::print_stack_trace_at(regs);
if (!is_in_kernel(regs))
{
// FIXME: Kill this process with SIGSEGV once we have signals and all that.
@ -105,8 +107,6 @@ void decode_page_fault_error_code(u64 code)
unreachable();
}
CPU::print_stack_trace_at(regs);
CPU::efficient_halt();
}
@ -118,6 +118,31 @@ void decode_page_fault_error_code(u64 code)
CPU::print_stack_trace_at(regs);
if (!is_in_kernel(regs))
{
// FIXME: Kill this process with SIGSEGV once we have signals and all that.
kerrorln("Current task %zu was terminated because of a general protection fault", Scheduler::current()->id);
if (Scheduler::current()->is_kernel) Scheduler::current()->state = ThreadState::Dying;
else
{
auto* current = Scheduler::current();
auto* parent = current->parent;
if (parent && parent->state == ThreadState::Waiting)
{
auto child = *parent->child_being_waited_for;
if (child == -1 || child == (pid_t)current->id)
{
parent->child_being_waited_for = (pid_t)current->id;
parent->wake_up();
}
}
current->state = ThreadState::Exited;
}
Scheduler::current()->status = 127;
kernel_yield();
unreachable();
}
CPU::efficient_halt();
}
@ -302,14 +327,14 @@ namespace CPU
asm volatile("hlt");
}
[[noreturn]] void efficient_halt() // Halt the CPU, using the lowest power possible. On x86-64 we do this using the
// "hlt" instruction, which puts the CPU into a low-power idle state until the
// next interrupt arrives... and we disable interrupts beforehand.
[[noreturn]] void efficient_halt() // Halt the CPU, using the lowest power possible. On x86-64 we do this using
// the "hlt" instruction, which puts the CPU into a low-power idle state
// until the next interrupt arrives... and we disable interrupts beforehand.
{
asm volatile("cli"); // Disable interrupts
loop:
asm volatile("hlt"); // Let the cpu rest and pause until the next interrupt arrives... which in this case should
// be never (unless an NMI arrives) :)
asm volatile("hlt"); // Let the cpu rest and pause until the next interrupt arrives... which in this case
// should be never (unless an NMI arrives) :)
goto loop; // Safeguard: if we ever wake up, start our low-power rest again
}

View File

@ -1,6 +1,7 @@
#include "thread/ThreadImage.h"
#include "memory/MemoryManager.h"
#include "thread/Thread.h"
#include <luna/Alignment.h>
#include <luna/CString.h>
static constexpr usize DEFAULT_USER_STACK_PAGES = 6;
@ -122,7 +123,7 @@ void ThreadImage::apply(Thread* thread)
thread->kernel_stack = m_kernel_stack;
thread->stack = m_user_stack;
thread->set_sp(m_sp);
thread->set_sp(align_down<16>(m_sp));
thread->directory = m_directory;

View File

@ -27,6 +27,9 @@ extern FILE* stderr;
#define stderr stderr
#define BUFSIZ 1024
#define FILENAME_MAX \
1024 // As Luna does not impose a limit on this, this is the recommended size for character arrays holding a file
// name.
#ifdef __cplusplus
extern "C"
@ -41,6 +44,9 @@ extern "C"
/* Bind a stream to a file descriptor. */
FILE* fdopen(int fd, const char* mode);
/* Change the underlying file and mode of a stream. */
FILE* freopen(const char* path, const char* mode, FILE* stream);
/* Close a file and frees up its stream. */
int fclose(FILE* stream);
@ -95,6 +101,9 @@ extern "C"
/* Read a character from standard input. */
int getchar(void);
/* Push a character back to stream so that it can be read again. */
int ungetc(int c, FILE* stream);
/* Read a line from stream. */
char* fgets(char* buf, size_t size, FILE* stream);

View File

@ -46,6 +46,12 @@ static int fdopen_check_compatible_mode(int fd, int new_flags)
extern "C"
{
int fflush(FILE*)
{
// FIXME: Files are not buffered right now.
return 0;
}
FILE* fopen(const char* path, const char* mode)
{
int flags;
@ -85,6 +91,25 @@ extern "C"
return f;
}
FILE* freopen(const char* path, const char* mode, FILE* stream)
{
int flags;
if ((flags = fopen_parse_mode(mode)) < 0) return nullptr;
close(stream->_fd);
if (!path) { fail("FIXME: freopen() called with path=nullptr"); }
int fd = open(path, flags, 0666);
if (fd < 0) { return nullptr; }
stream->_fd = fd;
clearerr(stream);
return stream;
}
int fclose(FILE* stream)
{
if (close(stream->_fd) < 0) return EOF;
@ -460,4 +485,9 @@ extern "C"
if (!f) close(fd);
return f;
}
int ungetc(int, FILE*)
{
fail("FIXME: ungetc: not implemented");
}
}

View File

@ -503,15 +503,18 @@ usize vstring_format(char* buf, usize max, const char* format, va_list ap)
[](char c, void* arg) -> Result<void> {
StringFormatInfo* info_arg = (StringFormatInfo*)arg;
if (!info_arg->remaining) return {};
*(info_arg->buffer) = c;
info_arg->buffer++;
if (info_arg->buffer)
{
*(info_arg->buffer) = c;
info_arg->buffer++;
}
info_arg->remaining--;
return {};
},
&info, ap)
.value();
*(info.buffer) = 0;
if (info.buffer) *(info.buffer) = 0;
return result;
}

View File

@ -6,5 +6,5 @@ Stack::Stack(u64 base, usize bytes) : m_base(base), m_bytes(bytes)
u64 Stack::top() const
{
return (m_base + m_bytes) - sizeof(void*);
return (m_base + m_bytes) - 16;
}