diff options
| author | hachem <im@hachem.wtf> | 2026-08-27 14:17:34 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-27 14:17:34 +0200 |
| commit | 705e3914e4e820c3ac92892c32c93479691a09e7 (patch) | |
| tree | bad8932559620328da060ea45245fcabec2332f2 /src/debugger/debugger.h | |
| parent | 90398614bcc9e1c1bde7a0f65a0db66173a1d8b4 (diff) | |
add: debugger interface
Diffstat (limited to 'src/debugger/debugger.h')
| -rw-r--r-- | src/debugger/debugger.h | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/debugger/debugger.h b/src/debugger/debugger.h new file mode 100644 index 0000000..c810417 --- /dev/null +++ b/src/debugger/debugger.h @@ -0,0 +1,99 @@ +#pragma once + +#include "core/result.h" +#include "debugger/types.h" + +#include <cstdint> +#include <filesystem> +#include <span> +#include <string> +#include <string_view> +#include <vector> + +namespace Hsdbg +{ + class Debugger + { + public: + Debugger(); + ~Debugger(); + + Debugger(const Debugger&) = delete; + Debugger(Debugger&&) = delete; + auto operator=(const Debugger&) -> Debugger& = delete; + auto operator=(Debugger&&) -> Debugger& = delete; + + // target lifetime + auto load_target(const std::filesystem::path& executable) -> Result<void>; + auto unload_target() -> void; + auto launch(const LaunchSpec& spec) -> Result<void>; + auto attach(uint64_t process_id) -> Result<void>; + auto detach() -> Result<void>; + auto terminate() -> Result<void>; + + // execution control + auto resume() -> Result<void>; + auto pause() -> Result<void>; + auto step_over(StepMode mode = StepMode::Line) -> Result<void>; + auto step_into(StepMode mode = StepMode::Line) -> Result<void>; + auto step_out() -> Result<void>; + auto run_to(const std::filesystem::path& file, uint32_t line) -> Result<void>; + + // breakpoints, the only part that keeps real state for now + auto add_breakpoint(const std::filesystem::path& file, uint32_t line) -> uint32_t; + auto add_function_breakpoint(std::string_view function) -> uint32_t; + auto remove_breakpoint(uint32_t id) -> bool; + auto set_breakpoint_enabled(uint32_t id, bool enabled) -> bool; + auto clear_breakpoints() -> void; + auto find_breakpoint(uint32_t id) -> Breakpoint*; + auto breakpoints() const -> std::span<const Breakpoint> { return m_breakpoints; } + + // inspection + auto threads() const -> std::span<const Thread> { return m_threads; } + auto call_stack() const -> std::span<const StackFrame> { return m_call_stack; } + auto locals() const -> std::span<const Variable> { return m_locals; } + auto registers() const -> std::span<const Register> { return m_registers; } + auto evaluate(std::string_view expression) -> Result<std::string>; + auto read_memory(uint64_t address, size_t size) -> Result<std::vector<uint8_t>>; + auto console_output() const -> std::span<const std::string> { return m_console_output; } + + // selection, what the ui is currently looking at + auto select_thread(uint64_t thread_id) -> bool; + auto select_frame(uint32_t frame_index) -> bool; + auto selected_thread() const -> uint64_t { return m_selected_thread; } + auto selected_frame() const -> uint32_t { return m_selected_frame; } + + // pumps whatever the debug session has to say, called once per frame + auto update() -> void; + + auto state() const -> TargetState { return m_state; } + auto stop_reason() const -> StopReason { return m_stop_reason; } + auto target_path() const -> const std::filesystem::path& { return m_target_path; } + auto process_id() const -> uint64_t { return m_process_id; } + + auto has_target() const -> bool { return m_state != TargetState::NoTarget; } + auto is_running() const -> bool { return m_state == TargetState::Running; } + auto is_stopped() const -> bool { return m_state == TargetState::Stopped; } + + private: + auto set_state(TargetState state) -> void; + + TargetState m_state = TargetState::NoTarget; + StopReason m_stop_reason = StopReason::None; + + std::filesystem::path m_target_path; + uint64_t m_process_id = 0; + + std::vector<Breakpoint> m_breakpoints; + uint32_t m_next_breakpoint_id = 1; + + std::vector<Thread> m_threads; + std::vector<StackFrame> m_call_stack; + std::vector<Variable> m_locals; + std::vector<Register> m_registers; + std::vector<std::string> m_console_output; + + uint64_t m_selected_thread = 0; + uint32_t m_selected_frame = 0; + }; +} |
