summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2023-02-19 22:52:52 +0200
committerAndreas Kling <kling@serenityos.org>2023-02-24 19:09:27 +0100
commit47f5a3ea9afeaade0295022c7e01fdc54401ef9f (patch)
tree800bff0439556de2e760c1734dc624ea3040fcee
parent91224d47d20ab149ddf41e681ea6367c50123323 (diff)
downloadserenity-47f5a3ea9afeaade0295022c7e01fdc54401ef9f.zip
HackStudio: Add 'pause debuggee' button
This button sends a SIGSTOP to the debugged process, which pauses it. The debuggee can be resumed with the 'continue' button.
-rw-r--r--Base/res/icons/16x16/debug-pause.pngbin0 -> 4979 bytes
-rw-r--r--Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp27
-rw-r--r--Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.h8
-rw-r--r--Userland/DevTools/HackStudio/Debugger/Debugger.cpp4
-rw-r--r--Userland/DevTools/HackStudio/Debugger/Debugger.h2
-rw-r--r--Userland/DevTools/HackStudio/HackStudioWidget.cpp6
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.cpp5
-rw-r--r--Userland/Libraries/LibDebug/DebugSession.h3
8 files changed, 44 insertions, 11 deletions
diff --git a/Base/res/icons/16x16/debug-pause.png b/Base/res/icons/16x16/debug-pause.png
new file mode 100644
index 0000000000..a93a815ea3
--- /dev/null
+++ b/Base/res/icons/16x16/debug-pause.png
Binary files differ
diff --git a/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp b/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
index ba03e124c4..788564e94b 100644
--- a/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
+++ b/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
@@ -40,12 +40,17 @@ ErrorOr<void> DebugInfoWidget::init_toolbar()
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::SourceStepOut);
});
+ m_pause_action = GUI::Action::create("Pause", {}, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/debug-pause.png"sv)), [](auto&) {
+ Debugger::the().stop_debuggee();
+ });
+
m_toolbar->add_action(*m_continue_action);
m_toolbar->add_action(*m_singlestep_action);
m_toolbar->add_action(*m_step_in_action);
m_toolbar->add_action(*m_step_out_action);
+ m_toolbar->add_action(*m_pause_action);
- set_debug_actions_enabled(false);
+ set_debug_actions_enabled(false, {});
return {};
}
@@ -193,12 +198,22 @@ void DebugInfoWidget::program_stopped()
m_registers_view->set_model({});
}
-void DebugInfoWidget::set_debug_actions_enabled(bool enabled)
+void DebugInfoWidget::set_debug_actions_enabled(bool enabled, Optional<DebugActionsState> state)
{
- m_continue_action->set_enabled(enabled);
- m_singlestep_action->set_enabled(enabled);
- m_step_in_action->set_enabled(enabled);
- m_step_out_action->set_enabled(enabled);
+ if (!enabled) {
+ m_continue_action->set_enabled(false);
+ m_singlestep_action->set_enabled(false);
+ m_step_in_action->set_enabled(false);
+ m_step_out_action->set_enabled(false);
+ m_pause_action->set_enabled(false);
+ return;
+ }
+
+ m_continue_action->set_enabled(state == DebugActionsState::DebuggeeStopped);
+ m_singlestep_action->set_enabled(state == DebugActionsState::DebuggeeStopped);
+ m_step_in_action->set_enabled(state == DebugActionsState::DebuggeeStopped);
+ m_step_out_action->set_enabled(state == DebugActionsState::DebuggeeStopped);
+ m_pause_action->set_enabled(state == DebugActionsState::DebuggeeRunning);
}
}
diff --git a/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.h b/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.h
index 11759c649d..e08b23dfae 100644
--- a/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.h
+++ b/Userland/DevTools/HackStudio/Debugger/DebugInfoWidget.h
@@ -29,7 +29,12 @@ public:
void update_state(Debug::ProcessInspector&, PtraceRegisters const&);
void program_stopped();
- void set_debug_actions_enabled(bool enabled);
+
+ enum class DebugActionsState {
+ DebuggeeRunning,
+ DebuggeeStopped,
+ };
+ void set_debug_actions_enabled(bool enabled, Optional<DebugActionsState>);
Function<void(Debug::DebugInfo::SourcePosition const&)> on_backtrace_frame_selection;
@@ -51,6 +56,7 @@ private:
RefPtr<GUI::Action> m_singlestep_action;
RefPtr<GUI::Action> m_step_in_action;
RefPtr<GUI::Action> m_step_out_action;
+ RefPtr<GUI::Action> m_pause_action;
};
}
diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp
index b1a97bae4c..2ab1a0cbc8 100644
--- a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp
+++ b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp
@@ -314,5 +314,9 @@ void Debugger::set_requested_debugger_action(DebuggerAction action)
pthread_cond_signal(continue_cond());
pthread_mutex_unlock(continue_mutex());
}
+void Debugger::stop_debuggee()
+{
+ return m_debug_session->stop_debuggee();
+}
}
diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.h b/Userland/DevTools/HackStudio/Debugger/Debugger.h
index eafd7382ba..656d2983c4 100644
--- a/Userland/DevTools/HackStudio/Debugger/Debugger.h
+++ b/Userland/DevTools/HackStudio/Debugger/Debugger.h
@@ -64,6 +64,8 @@ public:
void set_child_setup_callback(Function<ErrorOr<void>()> callback) { m_child_setup_callback = move(callback); }
+ void stop_debuggee();
+
private:
class DebuggingState {
public:
diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp
index 71d9eb486c..aa8b5be432 100644
--- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp
+++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp
@@ -1055,7 +1055,7 @@ void HackStudioWidget::initialize_debugger()
if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().set_execution_position(source_position.value().line_number - 1);
m_debug_info_widget->update_state(*Debugger::the().session(), regs);
- m_debug_info_widget->set_debug_actions_enabled(true);
+ m_debug_info_widget->set_debug_actions_enabled(true, DebugInfoWidget::DebugActionsState::DebuggeeStopped);
m_disassembly_widget->update_state(*Debugger::the().session(), regs);
HackStudioWidget::reveal_action_tab(*m_debug_info_widget);
});
@@ -1065,7 +1065,7 @@ void HackStudioWidget::initialize_debugger()
},
[this]() {
GUI::Application::the()->event_loop().deferred_invoke([this] {
- m_debug_info_widget->set_debug_actions_enabled(false);
+ m_debug_info_widget->set_debug_actions_enabled(true, DebugInfoWidget::DebugActionsState::DebuggeeRunning);
if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().clear_execution_position();
});
@@ -1073,7 +1073,7 @@ void HackStudioWidget::initialize_debugger()
},
[this]() {
GUI::Application::the()->event_loop().deferred_invoke([this] {
- m_debug_info_widget->set_debug_actions_enabled(false);
+ m_debug_info_widget->set_debug_actions_enabled(false, {});
if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().clear_execution_position();
m_debug_info_widget->program_stopped();
diff --git a/Userland/Libraries/LibDebug/DebugSession.cpp b/Userland/Libraries/LibDebug/DebugSession.cpp
index 7ad41b67db..451d4a17a2 100644
--- a/Userland/Libraries/LibDebug/DebugSession.cpp
+++ b/Userland/Libraries/LibDebug/DebugSession.cpp
@@ -510,4 +510,9 @@ void DebugSession::update_loaded_libs()
});
}
+void DebugSession::stop_debuggee()
+{
+ kill(pid(), SIGSTOP);
+}
+
}
diff --git a/Userland/Libraries/LibDebug/DebugSession.h b/Userland/Libraries/LibDebug/DebugSession.h
index 8997cea5dc..70b7ce43d3 100644
--- a/Userland/Libraries/LibDebug/DebugSession.h
+++ b/Userland/Libraries/LibDebug/DebugSession.h
@@ -100,6 +100,7 @@ public:
Syscall,
};
void continue_debuggee(ContinueType type = ContinueType::FreeRun);
+ void stop_debuggee();
// Returns the wstatus result of waitpid()
int continue_debuggee_and_wait(ContinueType type = ContinueType::FreeRun);
@@ -169,7 +170,7 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
// FIXME: This check actually only checks whether the debuggee
// stopped because it hit a breakpoint/syscall/is in single stepping mode or not
- if (WSTOPSIG(wstatus) != SIGTRAP) {
+ if (WSTOPSIG(wstatus) != SIGTRAP && WSTOPSIG(wstatus) != SIGSTOP) {
callback(DebugBreakReason::Exited, Optional<PtraceRegisters>());
m_is_debuggee_dead = true;
return true;