diff --git a/Userland/Libraries/LibCoredump/CMakeLists.txt b/Userland/Libraries/LibCoredump/CMakeLists.txt index ec2bb5e8d7..90fc8dba4e 100644 --- a/Userland/Libraries/LibCoredump/CMakeLists.txt +++ b/Userland/Libraries/LibCoredump/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES Backtrace.cpp + Inspector.cpp Reader.cpp ) diff --git a/Userland/Libraries/LibCoredump/Inspector.cpp b/Userland/Libraries/LibCoredump/Inspector.cpp new file mode 100644 index 0000000000..d5b7935bc8 --- /dev/null +++ b/Userland/Libraries/LibCoredump/Inspector.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021, Itamar S. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "Inspector.h" + +namespace Coredump { + +OwnPtr Inspector::create(String const& coredump_path, Function 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, Function 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 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(file_or_error.value()->bytes()); + auto debug_info = make(*image, String {}, library.base_address); + m_loaded_libraries.append(make(library.name, file_or_error.value(), move(image), move(debug_info), library.base_address)); + }); +} + +bool Inspector::poke(void*, FlatPtr) { return false; } + +Optional 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 func) const +{ + for (auto& library : m_loaded_libraries) { + if (func(library) == IterationDecision::Break) + break; + } +} + +} diff --git a/Userland/Libraries/LibCoredump/Inspector.h b/Userland/Libraries/LibCoredump/Inspector.h new file mode 100644 index 0000000000..af92235707 --- /dev/null +++ b/Userland/Libraries/LibCoredump/Inspector.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, Itamar S. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Reader.h" +#include +#include + +namespace Coredump { + +class Inspector : public Debug::ProcessInspector { + AK_MAKE_NONCOPYABLE(Inspector); + AK_MAKE_NONMOVABLE(Inspector); + +public: + static OwnPtr create(String const& coredump_path, Function on_progress = {}); + virtual ~Inspector() override = default; + + // ^Debug::ProcessInspector + virtual bool poke(void* address, FlatPtr data) override; + virtual Optional 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) const override; + +private: + Inspector(NonnullOwnPtr&&, Function on_progress); + + void parse_loaded_libraries(Function on_progress); + size_t number_of_libraries_in_coredump() const; + + NonnullOwnPtr m_reader; + + NonnullOwnPtrVector m_loaded_libraries; +}; + +} diff --git a/Userland/Libraries/LibCoredump/Reader.cpp b/Userland/Libraries/LibCoredump/Reader.cpp index ae3ddbaa1c..db5ed3f60a 100644 --- a/Userland/Libraries/LibCoredump/Reader.cpp +++ b/Userland/Libraries/LibCoredump/Reader.cpp @@ -15,7 +15,7 @@ namespace Coredump { -OwnPtr Reader::create(const String& path) +OwnPtr Reader::create(StringView path) { auto file_or_error = MappedFile::map(path); if (file_or_error.is_error()) diff --git a/Userland/Libraries/LibCoredump/Reader.h b/Userland/Libraries/LibCoredump/Reader.h index 911e1e4ed6..b6241ba754 100644 --- a/Userland/Libraries/LibCoredump/Reader.h +++ b/Userland/Libraries/LibCoredump/Reader.h @@ -20,7 +20,7 @@ class Reader { AK_MAKE_NONMOVABLE(Reader); public: - static OwnPtr create(const String&); + static OwnPtr create(StringView); ~Reader(); template