Selaa lähdekoodia

LibCoredump: Add Coredump::Inspector

The coredump Inspector implements the ProcessInspector interface for
a coredump. It is implemented using Coredump::Reader.
Itamar 3 vuotta sitten
vanhempi
commit
1c0a7cde63

+ 1 - 0
Userland/Libraries/LibCoredump/CMakeLists.txt

@@ -1,5 +1,6 @@
 set(SOURCES
 set(SOURCES
     Backtrace.cpp
     Backtrace.cpp
+    Inspector.cpp
     Reader.cpp
     Reader.cpp
 )
 )
 
 

+ 81 - 0
Userland/Libraries/LibCoredump/Inspector.cpp

@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "Inspector.h"
+
+namespace Coredump {
+
+OwnPtr<Inspector> Inspector::create(String const& coredump_path, Function<void(float)> on_progress)
+{
+    auto reader = Reader::create(coredump_path);
+    if (!reader)
+        return {};
+    return AK::adopt_own_if_nonnull(new (nothrow) Inspector(reader.release_nonnull(), move(on_progress)));
+}
+
+Inspector::Inspector(NonnullOwnPtr<Reader>&& reader, Function<void(float)> on_progress)
+    : m_reader(move(reader))
+{
+    parse_loaded_libraries(move(on_progress));
+}
+
+size_t Inspector::number_of_libraries_in_coredump() const
+{
+    size_t count = 0;
+    m_reader->for_each_library([&count](Coredump::Reader::LibraryInfo) {
+        ++count;
+    });
+    return count;
+}
+
+void Inspector::parse_loaded_libraries(Function<void(float)> on_progress)
+{
+    size_t number_of_libraries = number_of_libraries_in_coredump();
+    size_t library_index = 0;
+
+    m_reader->for_each_library([this, number_of_libraries, &library_index, &on_progress](Coredump::Reader::LibraryInfo library) {
+        ++library_index;
+        if (on_progress)
+            on_progress(library_index / (float)number_of_libraries);
+
+        auto file_or_error = MappedFile::map(library.path);
+        if (file_or_error.is_error())
+            return;
+
+        auto image = make<ELF::Image>(file_or_error.value()->bytes());
+        auto debug_info = make<Debug::DebugInfo>(*image, String {}, library.base_address);
+        m_loaded_libraries.append(make<Debug::LoadedLibrary>(library.name, file_or_error.value(), move(image), move(debug_info), library.base_address));
+    });
+}
+
+bool Inspector::poke(void*, FlatPtr) { return false; }
+
+Optional<FlatPtr> Inspector::peek(void* address) const
+{
+    return m_reader->peek_memory((FlatPtr)address);
+}
+
+PtraceRegisters Inspector::get_registers() const
+{
+    PtraceRegisters registers {};
+    m_reader->for_each_thread_info([&](ELF::Core::ThreadInfo const& thread_info) {
+        registers = thread_info.regs;
+        return IterationDecision::Break;
+    });
+    return registers;
+}
+
+void Inspector::set_registers(PtraceRegisters const&) {};
+
+void Inspector::for_each_loaded_library(Function<IterationDecision(Debug::LoadedLibrary const&)> func) const
+{
+    for (auto& library : m_loaded_libraries) {
+        if (func(library) == IterationDecision::Break)
+            break;
+    }
+}
+
+}

+ 41 - 0
Userland/Libraries/LibCoredump/Inspector.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "Reader.h"
+#include <AK/Noncopyable.h>
+#include <LibDebug/ProcessInspector.h>
+
+namespace Coredump {
+
+class Inspector : public Debug::ProcessInspector {
+    AK_MAKE_NONCOPYABLE(Inspector);
+    AK_MAKE_NONMOVABLE(Inspector);
+
+public:
+    static OwnPtr<Inspector> create(String const& coredump_path, Function<void(float)> on_progress = {});
+    virtual ~Inspector() override = default;
+
+    // ^Debug::ProcessInspector
+    virtual bool poke(void* address, FlatPtr data) override;
+    virtual Optional<FlatPtr> peek(void* address) const override;
+    virtual PtraceRegisters get_registers() const override;
+    virtual void set_registers(PtraceRegisters const&) override;
+    virtual void for_each_loaded_library(Function<IterationDecision(Debug::LoadedLibrary const&)>) const override;
+
+private:
+    Inspector(NonnullOwnPtr<Reader>&&, Function<void(float)> on_progress);
+
+    void parse_loaded_libraries(Function<void(float)> on_progress);
+    size_t number_of_libraries_in_coredump() const;
+
+    NonnullOwnPtr<Reader> m_reader;
+
+    NonnullOwnPtrVector<Debug::LoadedLibrary> m_loaded_libraries;
+};
+
+}

+ 1 - 1
Userland/Libraries/LibCoredump/Reader.cpp

@@ -15,7 +15,7 @@
 
 
 namespace Coredump {
 namespace Coredump {
 
 
-OwnPtr<Reader> Reader::create(const String& path)
+OwnPtr<Reader> Reader::create(StringView path)
 {
 {
     auto file_or_error = MappedFile::map(path);
     auto file_or_error = MappedFile::map(path);
     if (file_or_error.is_error())
     if (file_or_error.is_error())

+ 1 - 1
Userland/Libraries/LibCoredump/Reader.h

@@ -20,7 +20,7 @@ class Reader {
     AK_MAKE_NONMOVABLE(Reader);
     AK_MAKE_NONMOVABLE(Reader);
 
 
 public:
 public:
-    static OwnPtr<Reader> create(const String&);
+    static OwnPtr<Reader> create(StringView);
     ~Reader();
     ~Reader();
 
 
     template<typename Func>
     template<typename Func>