Skip to content

Commit

Permalink
Kernel: Exclude userspace heap memory from coredumps by default
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
awesomekling committed Sep 30, 2021
1 parent 94d0562 commit eeb4f2f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
35 changes: 33 additions & 2 deletions Kernel/Coredump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@
#include <LibC/elf.h>
#include <LibELF/Core.h>

#define INCLUDE_USERSPACE_HEAP_MEMORY_IN_COREDUMPS 0

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)
{
if (!process->is_dumpable()) {
Expand All @@ -37,8 +44,16 @@ KResultOr<NonnullOwnPtr<Coredump>> Coredump::try_create(NonnullRefPtr<Process> p
Coredump::Coredump(NonnullRefPtr<Process> process, NonnullRefPtr<OpenFileDescription> description)
: m_process(move(process))
, 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)
Expand Down Expand Up @@ -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));
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 {};

phdr.p_type = PT_LOAD;
Expand Down Expand Up @@ -147,8 +168,12 @@ KResult Coredump::write_program_headers(size_t notes_size)
KResult Coredump::write_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;
#endif

region->set_readable(true);
region->remap();
Expand Down Expand Up @@ -227,6 +252,12 @@ KResult Coredump::create_notes_regions_data(auto& builder) const
{
size_t region_index = 0;
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 {};
info.header.type = ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo;

Expand Down
2 changes: 1 addition & 1 deletion Kernel/Coredump.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Coredump {

NonnullRefPtr<Process> m_process;
NonnullRefPtr<OpenFileDescription> m_description;
const size_t m_num_program_headers;
size_t m_num_program_headers { 0 };
};

}

0 comments on commit eeb4f2f

Please sign in to comment.