mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-23 19:42:53 +00:00
HackStudio: Add ability to attach debugger to a running process
This commit is contained in:
parent
eb16513165
commit
ff6fb2cb10
Notes:
sideshowbarker
2024-07-16 23:50:09 +09:00
Author: https://github.com/itamar8910
Commit: ff6fb2cb10
Pull-request: https://github.com/SerenityOS/serenity/pull/17544
4 changed files with 52 additions and 12 deletions
|
@ -112,14 +112,8 @@ void Debugger::stop()
|
||||||
|
|
||||||
void Debugger::start()
|
void Debugger::start()
|
||||||
{
|
{
|
||||||
|
auto [debug_session, initial_state] = create_debug_session();
|
||||||
auto child_setup_callback = [this]() {
|
m_debug_session = move(debug_session);
|
||||||
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);
|
|
||||||
|
|
||||||
for (auto const& breakpoint : m_breakpoints) {
|
for (auto const& breakpoint : m_breakpoints) {
|
||||||
dbgln("inserting breakpoint at: {}:{}", breakpoint.file_path, breakpoint.line_number);
|
dbgln("inserting breakpoint at: {}:{}", breakpoint.file_path, breakpoint.line_number);
|
||||||
|
@ -132,14 +126,36 @@ void Debugger::start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debugger_loop();
|
debugger_loop(initial_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Debugger::debugger_loop()
|
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(Debug::DebugSession::DesiredInitialDebugeeState initial_state)
|
||||||
{
|
{
|
||||||
VERIFY(m_debug_session);
|
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) {
|
if (reason == Debug::DebugSession::DebugBreakReason::Exited) {
|
||||||
dbgln("Program exited");
|
dbgln("Program exited");
|
||||||
m_on_exit_callback();
|
m_on_exit_callback();
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
|
|
||||||
void set_executable_path(DeprecatedString const& path) { m_executable_path = path; }
|
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_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(); }
|
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);
|
Debug::DebugInfo::SourcePosition create_source_position(DeprecatedString const& file, size_t line);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
int debugger_loop();
|
int debugger_loop(Debug::DebugSession::DesiredInitialDebugeeState);
|
||||||
|
|
||||||
void remove_temporary_breakpoints();
|
void remove_temporary_breakpoints();
|
||||||
void do_step_out(PtraceRegisters const&);
|
void do_step_out(PtraceRegisters const&);
|
||||||
|
@ -106,6 +107,12 @@ private:
|
||||||
void insert_temporary_breakpoint(FlatPtr address);
|
void insert_temporary_breakpoint(FlatPtr address);
|
||||||
void insert_temporary_breakpoint_at_return_address(PtraceRegisters const&);
|
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;
|
OwnPtr<Debug::DebugSession> m_debug_session;
|
||||||
DeprecatedString m_source_root;
|
DeprecatedString m_source_root;
|
||||||
DebuggingState m_state;
|
DebuggingState m_state;
|
||||||
|
@ -117,6 +124,7 @@ private:
|
||||||
Vector<Debug::DebugInfo::SourcePosition> m_breakpoints;
|
Vector<Debug::DebugInfo::SourcePosition> m_breakpoints;
|
||||||
|
|
||||||
DeprecatedString m_executable_path;
|
DeprecatedString m_executable_path;
|
||||||
|
Optional<pid_t> m_pid_to_attach;
|
||||||
|
|
||||||
Function<HasControlPassedToUser(PtraceRegisters const&)> m_on_stopped_callback;
|
Function<HasControlPassedToUser(PtraceRegisters const&)> m_on_stopped_callback;
|
||||||
Function<void()> m_on_continue_callback;
|
Function<void()> m_on_continue_callback;
|
||||||
|
|
|
@ -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)
|
void HackStudioWidget::for_each_open_file(Function<void(ProjectFile const&)> func)
|
||||||
{
|
{
|
||||||
for (auto& open_file : m_open_files) {
|
for (auto& open_file : m_open_files) {
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void open_coredump(DeprecatedString const& coredump_path);
|
void open_coredump(DeprecatedString const& coredump_path);
|
||||||
|
void debug_process(pid_t pid);
|
||||||
void for_each_open_file(Function<void(ProjectFile const&)>);
|
void for_each_open_file(Function<void(ProjectFile const&)>);
|
||||||
bool semantic_syntax_highlighting_is_enabled() const;
|
bool semantic_syntax_highlighting_is_enabled() const;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue