1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 19:48:12 +00:00

Kernel: Exclude userspace heap memory from coredumps by default

When a process with a large heap crashes (e.g WebContent), it gets very
cumbersome to dump out a huge amount of memory.

In the vast majority of cases, we're only interested in generating a
nice backtrace from the coredump, so let's have the kernel skip over
userspace heap regions when dumping memory for now.

This is not ideal, and almost a little bit ugly, but it does make
investigating 500 MiB WebContent crashes significantly easier for now.
This commit is contained in:
Andreas Kling 2021-09-30 17:52:02 +02:00
parent 94d0562569
commit eeb4f2fa9b
2 changed files with 34 additions and 3 deletions

View file

@ -21,8 +21,15 @@
#include <LibC/elf.h> #include <LibC/elf.h>
#include <LibELF/Core.h> #include <LibELF/Core.h>
#define INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS 0
namespace Kernel { namespace Kernel {
[[maybe_unused]] static bool looks_like_userspace_heap_region(Memory::Region const& region)
{
return region.name().starts_with("LibJS:"sv) || region.name().starts_with("malloc:"sv);
}
KResultOr<NonnullOwnPtr<Coredump>> Coredump::try_create(NonnullRefPtr<Process> process, StringView output_path) KResultOr<NonnullOwnPtr<Coredump>> Coredump::try_create(NonnullRefPtr<Process> process, StringView output_path)
{ {
if (!process->is_dumpable()) { if (!process->is_dumpable()) {
@ -37,8 +44,16 @@ KResultOr<NonnullOwnPtr<Coredump>> Coredump::try_create(NonnullRefPtr<Process> p
Coredump::Coredump(NonnullRefPtr<Process> process, NonnullRefPtr<OpenFileDescription> description) Coredump::Coredump(NonnullRefPtr<Process> process, NonnullRefPtr<OpenFileDescription> description)
: m_process(move(process)) : m_process(move(process))
, m_description(move(description)) , m_description(move(description))
, m_num_program_headers(m_process->address_space().region_count() + 1) // +1 for NOTE segment
{ {
m_num_program_headers = 0;
for ([[maybe_unused]] auto& region : m_process->address_space().regions()) {
#if !INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS
if (looks_like_userspace_heap_region(*region))
continue;
#endif
++m_num_program_headers;
}
++m_num_program_headers; // +1 for NOTE segment
} }
KResultOr<NonnullRefPtr<OpenFileDescription>> Coredump::try_create_target_file(Process const& process, StringView output_path) KResultOr<NonnullRefPtr<OpenFileDescription>> Coredump::try_create_target_file(Process const& process, StringView output_path)
@ -107,6 +122,12 @@ KResult Coredump::write_program_headers(size_t notes_size)
{ {
size_t offset = sizeof(ElfW(Ehdr)) + m_num_program_headers * sizeof(ElfW(Phdr)); size_t offset = sizeof(ElfW(Ehdr)) + m_num_program_headers * sizeof(ElfW(Phdr));
for (auto& region : m_process->address_space().regions()) { for (auto& region : m_process->address_space().regions()) {
#if !INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS
if (looks_like_userspace_heap_region(*region))
continue;
#endif
ElfW(Phdr) phdr {}; ElfW(Phdr) phdr {};
phdr.p_type = PT_LOAD; phdr.p_type = PT_LOAD;
@ -147,8 +168,12 @@ KResult Coredump::write_program_headers(size_t notes_size)
KResult Coredump::write_regions() KResult Coredump::write_regions()
{ {
for (auto& region : m_process->address_space().regions()) { for (auto& region : m_process->address_space().regions()) {
if (region->is_kernel()) VERIFY(!region->is_kernel());
#if !INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS
if (looks_like_userspace_heap_region(*region))
continue; continue;
#endif
region->set_readable(true); region->set_readable(true);
region->remap(); region->remap();
@ -227,6 +252,12 @@ KResult Coredump::create_notes_regions_data(auto& builder) const
{ {
size_t region_index = 0; size_t region_index = 0;
for (auto& region : m_process->address_space().regions()) { for (auto& region : m_process->address_space().regions()) {
#if !INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS
if (looks_like_userspace_heap_region(*region))
continue;
#endif
ELF::Core::MemoryRegionInfo info {}; ELF::Core::MemoryRegionInfo info {};
info.header.type = ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo; info.header.type = ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo;

View file

@ -37,7 +37,7 @@ private:
NonnullRefPtr<Process> m_process; NonnullRefPtr<Process> m_process;
NonnullRefPtr<OpenFileDescription> m_description; NonnullRefPtr<OpenFileDescription> m_description;
const size_t m_num_program_headers; size_t m_num_program_headers { 0 };
}; };
} }