1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 00:57:36 +00:00

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.
This commit is contained in:
Itamar 2023-02-19 22:52:52 +02:00 committed by Andreas Kling
parent 91224d47d2
commit 47f5a3ea9a
8 changed files with 44 additions and 11 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -40,12 +40,17 @@ ErrorOr<void> DebugInfoWidget::init_toolbar()
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::SourceStepOut); 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_continue_action);
m_toolbar->add_action(*m_singlestep_action); m_toolbar->add_action(*m_singlestep_action);
m_toolbar->add_action(*m_step_in_action); m_toolbar->add_action(*m_step_in_action);
m_toolbar->add_action(*m_step_out_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 {}; return {};
} }
@ -193,12 +198,22 @@ void DebugInfoWidget::program_stopped()
m_registers_view->set_model({}); 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); if (!enabled) {
m_singlestep_action->set_enabled(enabled); m_continue_action->set_enabled(false);
m_step_in_action->set_enabled(enabled); m_singlestep_action->set_enabled(false);
m_step_out_action->set_enabled(enabled); 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);
} }
} }

View file

@ -29,7 +29,12 @@ public:
void update_state(Debug::ProcessInspector&, PtraceRegisters const&); void update_state(Debug::ProcessInspector&, PtraceRegisters const&);
void program_stopped(); 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; 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_singlestep_action;
RefPtr<GUI::Action> m_step_in_action; RefPtr<GUI::Action> m_step_in_action;
RefPtr<GUI::Action> m_step_out_action; RefPtr<GUI::Action> m_step_out_action;
RefPtr<GUI::Action> m_pause_action;
}; };
} }

View file

@ -314,5 +314,9 @@ void Debugger::set_requested_debugger_action(DebuggerAction action)
pthread_cond_signal(continue_cond()); pthread_cond_signal(continue_cond());
pthread_mutex_unlock(continue_mutex()); pthread_mutex_unlock(continue_mutex());
} }
void Debugger::stop_debuggee()
{
return m_debug_session->stop_debuggee();
}
} }

View file

@ -64,6 +64,8 @@ public:
void set_child_setup_callback(Function<ErrorOr<void>()> callback) { m_child_setup_callback = move(callback); } void set_child_setup_callback(Function<ErrorOr<void>()> callback) { m_child_setup_callback = move(callback); }
void stop_debuggee();
private: private:
class DebuggingState { class DebuggingState {
public: public:

View file

@ -1055,7 +1055,7 @@ void HackStudioWidget::initialize_debugger()
if (m_current_editor_in_execution) if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().set_execution_position(source_position.value().line_number - 1); 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->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); m_disassembly_widget->update_state(*Debugger::the().session(), regs);
HackStudioWidget::reveal_action_tab(*m_debug_info_widget); HackStudioWidget::reveal_action_tab(*m_debug_info_widget);
}); });
@ -1065,7 +1065,7 @@ void HackStudioWidget::initialize_debugger()
}, },
[this]() { [this]() {
GUI::Application::the()->event_loop().deferred_invoke([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) if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().clear_execution_position(); m_current_editor_in_execution->editor().clear_execution_position();
}); });
@ -1073,7 +1073,7 @@ void HackStudioWidget::initialize_debugger()
}, },
[this]() { [this]() {
GUI::Application::the()->event_loop().deferred_invoke([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) if (m_current_editor_in_execution)
m_current_editor_in_execution->editor().clear_execution_position(); m_current_editor_in_execution->editor().clear_execution_position();
m_debug_info_widget->program_stopped(); m_debug_info_widget->program_stopped();

View file

@ -510,4 +510,9 @@ void DebugSession::update_loaded_libs()
}); });
} }
void DebugSession::stop_debuggee()
{
kill(pid(), SIGSTOP);
}
} }

View file

@ -100,6 +100,7 @@ public:
Syscall, Syscall,
}; };
void continue_debuggee(ContinueType type = ContinueType::FreeRun); void continue_debuggee(ContinueType type = ContinueType::FreeRun);
void stop_debuggee();
// Returns the wstatus result of waitpid() // Returns the wstatus result of waitpid()
int continue_debuggee_and_wait(ContinueType type = ContinueType::FreeRun); 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 // FIXME: This check actually only checks whether the debuggee
// stopped because it hit a breakpoint/syscall/is in single stepping mode or not // 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>()); callback(DebugBreakReason::Exited, Optional<PtraceRegisters>());
m_is_debuggee_dead = true; m_is_debuggee_dead = true;
return true; return true;