diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 8a75e1adcbc..85a6178ded7 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -121,6 +121,17 @@ rust_kernel::log(uint32_t level, char const *fmt, ...) { va_end(args); } +void +rust_kernel::fatal(char const *fmt, ...) { + char buf[BUF_BYTES]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + _log.trace_ln(NULL, (uint32_t)0, buf); + exit(1); + va_end(args); +} + void rust_kernel::pump_message_queues() { for (size_t i = 0; i < message_queues.length(); i++) { diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index bea5afd5de3..f61935c8c48 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -106,6 +106,7 @@ public: void log_all_scheduler_state(); void log(uint32_t level, char const *fmt, ...); + void fatal(char const *fmt, ...); virtual ~rust_kernel(); void *malloc(size_t size); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 05220f02606..d8ff9236aa6 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -21,6 +21,22 @@ extern "C" CDECL char const * str_buf(rust_task *task, rust_str *s); +#ifdef __i386__ +void +check_stack(rust_task *task) { + void *esp; + asm volatile("movl %%esp,%0" : "=r" (esp)); + if (esp < task->stk->data) + task->kernel->fatal("Out of stack space, sorry"); +} +#else +#warning "Stack checks are not supported on this architecture" +void +check_stack(rust_task *task) { + // TODO +} +#endif + extern "C" void upcall_grow_task(rust_task *task, size_t n_frame_bytes) { I(task->sched, false); @@ -463,6 +479,7 @@ upcall_get_type_desc(rust_task *task, size_t align, size_t n_descs, type_desc const **descs) { + check_stack(task); LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); LOG(task, cache, "upcall get_type_desc with size=%" PRIdPTR