diff options
author | Itamar <itamar8910@gmail.com> | 2023-02-18 13:14:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-02-24 19:09:27 +0100 |
commit | ff6fb2cb10a5b2223b8bba34bb725c70201d91c0 (patch) | |
tree | e5b8891411d3d00f7f7bf043911d117fd004c627 | |
parent | eb16513165c5417e347f87e0da95d55a574b9928 (diff) | |
download | serenity-ff6fb2cb10a5b2223b8bba34bb725c70201d91c0.zip |
HackStudio: Add ability to attach debugger to a running process
-rw-r--r-- | Userland/DevTools/HackStudio/Debugger/Debugger.cpp | 38 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/Debugger/Debugger.h | 10 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/HackStudioWidget.cpp | 15 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/HackStudioWidget.h | 1 |
4 files changed, 52 insertions, 12 deletions
diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp index c4b08efd92..9830042a60 100644 --- a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp +++ b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp @@ -112,14 +112,8 @@ void Debugger::stop() void Debugger::start() { - - auto child_setup_callback = [this]() { - if (m_child_setup_callback) - return m_child_setup_callback(); - return ErrorOr<void> {}; - }; - m_debug_session = Debug::DebugSession::exec_and_attach(m_executable_path, m_source_root, move(child_setup_callback)); - VERIFY(!!m_debug_session); + auto [debug_session, initial_state] = create_debug_session(); + m_debug_session = move(debug_session); for (auto const& breakpoint : m_breakpoints) { dbgln("inserting breakpoint at: {}:{}", breakpoint.file_path, breakpoint.line_number); @@ -132,14 +126,36 @@ void Debugger::start() } } - debugger_loop(); + debugger_loop(initial_state); +} + +Debugger::CreateDebugSessionResult Debugger::create_debug_session() +{ + if (!m_executable_path.is_null()) { + auto child_setup_callback = [this]() { + if (m_child_setup_callback) + return m_child_setup_callback(); + return ErrorOr<void> {}; + }; + auto debug_session = Debug::DebugSession::exec_and_attach(m_executable_path, m_source_root, move(child_setup_callback)); + VERIFY(!!debug_session); + return { debug_session.release_nonnull(), Debug::DebugSession::Running }; + } + + if (m_pid_to_attach.has_value()) { + auto debug_session = Debug::DebugSession::attach(m_pid_to_attach.value(), m_source_root); + VERIFY(!!debug_session); + return { debug_session.release_nonnull(), Debug::DebugSession::Stopped }; + } + + VERIFY_NOT_REACHED(); } -int Debugger::debugger_loop() +int Debugger::debugger_loop(Debug::DebugSession::DesiredInitialDebugeeState initial_state) { VERIFY(m_debug_session); - m_debug_session->run(Debug::DebugSession::DesiredInitialDebugeeState::Running, [this](Debug::DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) { + m_debug_session->run(initial_state, [this](Debug::DebugSession::DebugBreakReason reason, Optional<PtraceRegisters> optional_regs) { if (reason == Debug::DebugSession::DebugBreakReason::Exited) { dbgln("Program exited"); m_on_exit_callback(); diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.h b/Userland/DevTools/HackStudio/Debugger/Debugger.h index 67053543ff..edbd8a61ce 100644 --- a/Userland/DevTools/HackStudio/Debugger/Debugger.h +++ b/Userland/DevTools/HackStudio/Debugger/Debugger.h @@ -38,6 +38,7 @@ public: void set_executable_path(DeprecatedString const& path) { m_executable_path = path; } void set_source_root(DeprecatedString const& source_root) { m_source_root = source_root; } + void set_pid_to_attach(pid_t pid) { m_pid_to_attach = pid; } Debug::DebugSession* session() { return m_debug_session.ptr(); } @@ -98,7 +99,7 @@ private: Debug::DebugInfo::SourcePosition create_source_position(DeprecatedString const& file, size_t line); void start(); - int debugger_loop(); + int debugger_loop(Debug::DebugSession::DesiredInitialDebugeeState); void remove_temporary_breakpoints(); void do_step_out(PtraceRegisters const&); @@ -106,6 +107,12 @@ private: void insert_temporary_breakpoint(FlatPtr address); void insert_temporary_breakpoint_at_return_address(PtraceRegisters const&); + struct CreateDebugSessionResult { + NonnullOwnPtr<Debug::DebugSession> session; + Debug::DebugSession::DesiredInitialDebugeeState initial_state { Debug::DebugSession::Stopped }; + }; + CreateDebugSessionResult create_debug_session(); + OwnPtr<Debug::DebugSession> m_debug_session; DeprecatedString m_source_root; DebuggingState m_state; @@ -117,6 +124,7 @@ private: Vector<Debug::DebugInfo::SourcePosition> m_breakpoints; DeprecatedString m_executable_path; + Optional<pid_t> m_pid_to_attach; Function<HasControlPassedToUser(PtraceRegisters const&)> m_on_stopped_callback; Function<void()> m_on_continue_callback; diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index f698340168..1eb7e6ec52 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -1878,6 +1878,21 @@ void HackStudioWidget::open_coredump(DeprecatedString const& coredump_path) } } +void HackStudioWidget::debug_process(pid_t pid) +{ + open_project("/usr/src/serenity"); + Debugger::the().set_pid_to_attach(pid); + + m_debugger_thread = Threading::Thread::construct(Debugger::start_static); + m_debugger_thread->start(); + m_stop_action->set_enabled(true); + m_run_action->set_enabled(false); + + for (auto& editor_wrapper : m_all_editor_wrappers) { + editor_wrapper.set_debug_mode(true); + } +} + void HackStudioWidget::for_each_open_file(Function<void(ProjectFile const&)> func) { for (auto& open_file : m_open_files) { diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.h b/Userland/DevTools/HackStudio/HackStudioWidget.h index 47a8b87bff..e2f403a8f9 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.h +++ b/Userland/DevTools/HackStudio/HackStudioWidget.h @@ -76,6 +76,7 @@ public: }; void open_coredump(DeprecatedString const& coredump_path); + void debug_process(pid_t pid); void for_each_open_file(Function<void(ProjectFile const&)>); bool semantic_syntax_highlighting_is_enabled() const; |