summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-04-04 20:11:54 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-04 20:13:55 +0200
commit0b8226811f0340316e4b0b6c05342598f86e5cd1 (patch)
treec61eae382501b582700c68b9c4f09b51d0fa11be /Kernel
parente238435c4fdb3d556452badb9767790b4652f295 (diff)
downloadserenity-0b8226811f0340316e4b0b6c05342598f86e5cd1.zip
Kernel+CrashReporter: Add metadata about page faults to crash reports
Crash reports for page faults now tell you what kind of memory access failed and where. :^)
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Arch/i386/CPU.cpp16
-rw-r--r--Kernel/Process.cpp5
-rw-r--r--Kernel/Process.h1
3 files changed, 20 insertions, 2 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp
index 5f3ecfc129..4a3dba9529 100644
--- a/Kernel/Arch/i386/CPU.cpp
+++ b/Kernel/Arch/i386/CPU.cpp
@@ -284,7 +284,8 @@ void page_fault_handler(TrapFrame* trap)
PANIC("Attempt to access UNMAP_AFTER_INIT section");
}
- auto response = MM.handle_page_fault(PageFault(regs.exception_code, VirtualAddress(fault_address)));
+ PageFault fault { regs.exception_code, VirtualAddress { fault_address } };
+ auto response = MM.handle_page_fault(fault);
if (response == PageFaultResponse::ShouldCrash || response == PageFaultResponse::OutOfMemory) {
if (faulted_in_kernel && handle_safe_access_fault(regs, fault_address)) {
@@ -328,6 +329,18 @@ void page_fault_handler(TrapFrame* trap)
dbgln("Note: Address {} looks like a possible nullptr dereference", VirtualAddress(fault_address));
}
+ auto& current_process = current_thread->process();
+ if (current_process.is_user_process()) {
+ current_process.set_coredump_metadata("fault_address", String::formatted("{:p}", fault_address));
+ current_process.set_coredump_metadata("fault_type", fault.type() == PageFault::Type::PageNotPresent ? "NotPresent" : "ProtectionViolation");
+ String fault_access;
+ if (fault.is_instruction_fetch())
+ fault_access = "Execute";
+ else
+ fault_access = fault.access() == PageFault::Access::Read ? "Read" : "Write";
+ current_process.set_coredump_metadata("fault_access", fault_access);
+ }
+
handle_crash(regs, "Page Fault", SIGSEGV, response == PageFaultResponse::OutOfMemory);
} else if (response == PageFaultResponse::Continue) {
#if PAGE_FAULT_DEBUG
@@ -2397,7 +2410,6 @@ void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, con
kernel_regs.eip = ptrace_regs.eip;
kernel_regs.eflags = (kernel_regs.eflags & ~safe_eflags_mask) | (ptrace_regs.eflags & safe_eflags_mask);
}
-
}
#ifdef DEBUG
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 7899f5dacb..fb18f73796 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -727,4 +727,9 @@ void Process::set_dumpable(bool dumpable)
m_dumpable = dumpable;
}
+void Process::set_coredump_metadata(const String& key, String value)
+{
+ m_coredump_metadata.set(key, move(value));
+}
+
}
diff --git a/Kernel/Process.h b/Kernel/Process.h
index b1e864817d..7848baa312 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -494,6 +494,7 @@ public:
HashMap<String, String>& coredump_metadata() { return m_coredump_metadata; }
const HashMap<String, String>& coredump_metadata() const { return m_coredump_metadata; }
+ void set_coredump_metadata(const String& key, String value);
const NonnullRefPtrVector<Thread>& threads_for_coredump(Badge<CoreDump>) const { return m_threads_for_coredump; }