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
Notes: sideshowbarker 2024-07-18 03:17:19 +09:00
2 changed files with 34 additions and 3 deletions

View file

@ -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()) {
@ -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)
@ -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;
@ -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();
@ -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;

View file

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