summaryrefslogtreecommitdiff
path: root/Kernel/Process.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-06 21:11:38 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-06 22:28:23 +0200
commit6fe83b0ac4f734f0dfe159b99136a4c56c83a7d0 (patch)
tree00f7b5bbca6b6506413c95821e8ecb3e6c2f9002 /Kernel/Process.cpp
parentc633c1c2eab688284d9339a8c6dfab525e776aca (diff)
downloadserenity-6fe83b0ac4f734f0dfe159b99136a4c56c83a7d0.zip
Kernel: Crash the current process on OOM (instead of panicking kernel)
This patch adds PageFaultResponse::OutOfMemory which informs the fault handler that we were unable to allocate a necessary physical page and cannot continue. In response to this, the kernel will crash the current process. Because we are OOM, we can't symbolicate the crash like we normally would (since the ELF symbolication code needs to allocate), so we also communicate to Process::crash() that we're out of memory. Now we can survive "allocate 300 MB" (only the allocate process dies.) This is definitely not perfect and can easily end up killing a random innocent other process who happened to allocate one page at the wrong time, but it's a *lot* better than panicking on OOM. :^)
Diffstat (limited to 'Kernel/Process.cpp')
-rw-r--r--Kernel/Process.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 616fdff75e..2f25867518 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -1540,21 +1540,25 @@ int Process::sys$sigreturn(RegisterState& registers)
return smuggled_eax;
}
-void Process::crash(int signal, u32 eip)
+void Process::crash(int signal, u32 eip, bool out_of_memory)
{
ASSERT_INTERRUPTS_DISABLED();
ASSERT(!is_dead());
ASSERT(Process::current == this);
- if (eip >= 0xc0000000 && g_kernel_symbols_available) {
- auto* symbol = symbolicate_kernel_address(eip);
- dbg() << "\033[31;1m" << String::format("%p", eip) << " " << (symbol ? demangle(symbol->name) : "(k?)") << " +" << (symbol ? eip - symbol->address : 0) << "\033[0m\n";
- } else if (auto elf_bundle = this->elf_bundle()) {
- dbg() << "\033[31;1m" << String::format("%p", eip) << " " << elf_bundle->elf_loader->symbolicate(eip) << "\033[0m\n";
+ if (out_of_memory) {
+ dbg() << "\033[31;1mOut of memory\033[m, killing: " << *this;
} else {
- dbg() << "\033[31;1m" << String::format("%p", eip) << " (?)\033[0m\n";
+ if (eip >= 0xc0000000 && g_kernel_symbols_available) {
+ auto* symbol = symbolicate_kernel_address(eip);
+ dbg() << "\033[31;1m" << String::format("%p", eip) << " " << (symbol ? demangle(symbol->name) : "(k?)") << " +" << (symbol ? eip - symbol->address : 0) << "\033[0m\n";
+ } else if (auto elf_bundle = this->elf_bundle()) {
+ dbg() << "\033[31;1m" << String::format("%p", eip) << " " << elf_bundle->elf_loader->symbolicate(eip) << "\033[0m\n";
+ } else {
+ dbg() << "\033[31;1m" << String::format("%p", eip) << " (?)\033[0m\n";
+ }
+ dump_backtrace();
}
- dump_backtrace();
m_termination_signal = signal;
dump_regions();
ASSERT(is_ring3());