summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2023-02-18 13:14:19 +0200
committerAndreas Kling <kling@serenityos.org>2023-02-24 19:09:27 +0100
commitff6fb2cb10a5b2223b8bba34bb725c70201d91c0 (patch)
treee5b8891411d3d00f7f7bf043911d117fd004c627
parenteb16513165c5417e347f87e0da95d55a574b9928 (diff)
downloadserenity-ff6fb2cb10a5b2223b8bba34bb725c70201d91c0.zip
HackStudio: Add ability to attach debugger to a running process
-rw-r--r--Userland/DevTools/HackStudio/Debugger/Debugger.cpp38
-rw-r--r--Userland/DevTools/HackStudio/Debugger/Debugger.h10
-rw-r--r--Userland/DevTools/HackStudio/HackStudioWidget.cpp15
-rw-r--r--Userland/DevTools/HackStudio/HackStudioWidget.h1
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;