1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:37:34 +00:00

HackStudio: Detach from debugged process before terminating

Fixes #3308
This commit is contained in:
Itamar 2020-09-26 11:23:49 +03:00 committed by Andreas Kling
parent 8ce641cefc
commit 8af67210cf
6 changed files with 63 additions and 37 deletions

View file

@ -46,31 +46,19 @@ namespace HackStudio {
void DebugInfoWidget::init_toolbar()
{
m_continue_action = GUI::Action::create("Continue", Gfx::Bitmap::load_from_file("/res/icons/16x16/debug-continue.png"), [](auto&) {
pthread_mutex_lock(Debugger::the().continue_mutex());
Debugger::the().set_continue_type(Debugger::ContinueType::Continue);
pthread_cond_signal(Debugger::the().continue_cond());
pthread_mutex_unlock(Debugger::the().continue_mutex());
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::Continue);
});
m_singlestep_action = GUI::Action::create("Step Over", { Mod_None, Key_F10 }, Gfx::Bitmap::load_from_file("/res/icons/16x16/debug-step-over.png"), [](auto&) {
pthread_mutex_lock(Debugger::the().continue_mutex());
Debugger::the().set_continue_type(Debugger::ContinueType::SourceStepOver);
pthread_cond_signal(Debugger::the().continue_cond());
pthread_mutex_unlock(Debugger::the().continue_mutex());
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::SourceStepOver);
});
m_step_in_action = GUI::Action::create("Step In", { Mod_None, Key_F11 }, Gfx::Bitmap::load_from_file("/res/icons/16x16/debug-step-in.png"), [](auto&) {
pthread_mutex_lock(Debugger::the().continue_mutex());
Debugger::the().set_continue_type(Debugger::ContinueType::SourceSingleStep);
pthread_cond_signal(Debugger::the().continue_cond());
pthread_mutex_unlock(Debugger::the().continue_mutex());
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::SourceSingleStep);
});
m_step_out_action = GUI::Action::create("Step Out", { Mod_Shift, Key_F11 }, Gfx::Bitmap::load_from_file("/res/icons/16x16/debug-step-out.png"), [](auto&) {
pthread_mutex_lock(Debugger::the().continue_mutex());
Debugger::the().set_continue_type(Debugger::ContinueType::SourceStepOut);
pthread_cond_signal(Debugger::the().continue_cond());
pthread_mutex_unlock(Debugger::the().continue_mutex());
Debugger::the().set_requested_debugger_action(Debugger::DebuggerAction::SourceStepOut);
});
m_toolbar->add_action(*m_continue_action);

View file

@ -58,8 +58,8 @@ Debugger::Debugger(
, m_on_continue_callback(move(on_continue_callback))
, m_on_exit_callback(move(on_exit_callback))
{
pthread_mutex_init(&m_continue_mutex, nullptr);
pthread_cond_init(&m_continue_cond, nullptr);
pthread_mutex_init(&m_ui_action_mutex, nullptr);
pthread_cond_init(&m_ui_action_cond, nullptr);
}
void Debugger::on_breakpoint_change(const String& file, size_t line, BreakpointChange change_type)
@ -153,30 +153,38 @@ int Debugger::debugger_loop()
auto control_passed_to_user = m_on_stopped_callback(regs);
if (control_passed_to_user == HasControlPassedToUser::Yes) {
pthread_mutex_lock(&m_continue_mutex);
pthread_cond_wait(&m_continue_cond, &m_continue_mutex);
pthread_mutex_unlock(&m_continue_mutex);
pthread_mutex_lock(&m_ui_action_mutex);
pthread_cond_wait(&m_ui_action_cond, &m_ui_action_mutex);
pthread_mutex_unlock(&m_ui_action_mutex);
if (m_requested_debugger_action != DebuggerAction::Exit)
m_on_continue_callback();
m_on_continue_callback();
} else {
m_continue_type = ContinueType::Continue;
m_requested_debugger_action = DebuggerAction::Continue;
}
switch (m_continue_type) {
case ContinueType::Continue:
switch (m_requested_debugger_action) {
case DebuggerAction::Continue:
m_state.set_normal();
return Debug::DebugSession::DebugDecision::Continue;
case ContinueType::SourceSingleStep:
case DebuggerAction::SourceSingleStep:
m_state.set_single_stepping(source_position.value());
return Debug::DebugSession::DebugDecision::SingleStep;
case ContinueType::SourceStepOut:
case DebuggerAction::SourceStepOut:
m_state.set_stepping_out();
do_step_out(regs);
return Debug::DebugSession::DebugDecision::Continue;
case ContinueType::SourceStepOver:
case DebuggerAction::SourceStepOver:
m_state.set_stepping_over();
do_step_over(regs);
return Debug::DebugSession::DebugDecision::Continue;
case DebuggerAction::Exit:
// NOTE: Is detaching from the debugee the best thing to do here?
// We could display a dialog in the UI, remind the user that there is
// a live debugged process, and ask whether they want to terminate/detach.
dbg() << "Debugger exiting";
return Debug::DebugSession::DebugDecision::Detach;
}
ASSERT_NOT_REACHED();
});
@ -259,4 +267,12 @@ void Debugger::insert_temporary_breakpoint(FlatPtr address)
m_state.add_temporary_breakpoint(address);
}
void Debugger::set_requested_debugger_action(DebuggerAction action)
{
pthread_mutex_lock(continue_mutex());
m_requested_debugger_action = action;
pthread_cond_signal(continue_cond());
pthread_mutex_unlock(continue_mutex());
}
}

View file

@ -60,17 +60,18 @@ public:
// Thread entry point
static int start_static();
pthread_mutex_t* continue_mutex() { return &m_continue_mutex; }
pthread_cond_t* continue_cond() { return &m_continue_cond; }
pthread_mutex_t* continue_mutex() { return &m_ui_action_mutex; }
pthread_cond_t* continue_cond() { return &m_ui_action_cond; }
enum class ContinueType {
enum class DebuggerAction {
Continue,
SourceSingleStep,
SourceStepOut,
SourceStepOver,
Exit,
};
void set_continue_type(ContinueType type) { m_continue_type = type; }
void set_requested_debugger_action(DebuggerAction);
void reset_breakpoints() { m_breakpoints.clear(); }
private:
@ -119,8 +120,9 @@ private:
OwnPtr<Debug::DebugSession> m_debug_session;
DebuggingState m_state;
pthread_mutex_t m_continue_mutex {};
pthread_cond_t m_continue_cond {};
pthread_mutex_t m_ui_action_mutex {};
pthread_cond_t m_ui_action_cond {};
DebuggerAction m_requested_debugger_action { DebuggerAction::Continue };
Vector<Debug::DebugInfo::SourcePosition> m_breakpoints;
@ -129,8 +131,6 @@ private:
Function<HasControlPassedToUser(const PtraceRegisters&)> m_on_stopped_callback;
Function<void()> m_on_continue_callback;
Function<void()> m_on_exit_callback;
ContinueType m_continue_type { ContinueType::Continue };
};
}